<html>

<head>
<meta http-equiv="Content-Type" content="text/html; charset=gb2312">
<meta name=Generator content="Microsoft Word 14 (filtered)">
<style>
<!--
 /* Font Definitions */
 @font-face
	{font-family:Wingdings;
	panose-1:5 0 0 0 0 0 0 0 0 0;}
@font-face
	{font-family:宋体;
	panose-1:2 1 6 0 3 1 1 1 1 1;}
@font-face
	{font-family:黑体;
	panose-1:2 1 6 9 6 1 1 1 1 1;}
@font-face
	{font-family:黑体;
	panose-1:2 1 6 9 6 1 1 1 1 1;}
@font-face
	{font-family:方正小标宋简体;}
@font-face
	{font-family:"\@黑体";
	panose-1:2 1 6 9 6 1 1 1 1 1;}
@font-face
	{font-family:"\@宋体";
	panose-1:2 1 6 0 3 1 1 1 1 1;}
@font-face
	{font-family:"\@方正小标宋简体";}
 /* Style Definitions */
 p.MsoNormal, li.MsoNormal, div.MsoNormal
	{margin:0cm;
	margin-bottom:.0001pt;
	text-align:justify;
	text-justify:inter-ideograph;
	font-size:10.5pt;
	font-family:宋体;}
h1
	{mso-style-link:"标题 1 Char";
	margin-top:17.0pt;
	margin-right:0cm;
	margin-bottom:16.5pt;
	margin-left:7.2pt;
	text-align:center;
	text-indent:-7.2pt;
	page-break-after:avoid;
	font-size:22.0pt;
	font-family:宋体;
	font-weight:bold;}
h2
	{mso-style-link:"标题 2 Char";
	margin-top:13.0pt;
	margin-right:0cm;
	margin-bottom:13.0pt;
	margin-left:0cm;
	text-align:justify;
	text-justify:inter-ideograph;
	text-indent:0cm;
	page-break-after:avoid;
	font-size:16.0pt;
	font-family:"Arial","sans-serif";
	font-weight:bold;}
h3
	{mso-style-link:"标题 3 Char";
	margin:0cm;
	margin-bottom:.0001pt;
	text-align:justify;
	text-justify:inter-ideograph;
	text-indent:0cm;
	page-break-after:avoid;
	font-size:14.0pt;
	font-family:"Arial","sans-serif";
	font-weight:bold;}
h4
	{mso-style-link:"标题 4 Char";
	margin-top:0cm;
	margin-right:0cm;
	margin-bottom:0cm;
	margin-left:28.8pt;
	margin-bottom:.0001pt;
	text-align:justify;
	text-justify:inter-ideograph;
	text-indent:-28.8pt;
	page-break-after:avoid;
	font-size:12.0pt;
	font-family:"Arial","sans-serif";
	font-weight:bold;}
h5
	{mso-style-link:"标题 5 Char";
	margin-top:14.0pt;
	margin-right:0cm;
	margin-bottom:14.5pt;
	margin-left:36.0pt;
	text-align:justify;
	text-justify:inter-ideograph;
	text-indent:-36.0pt;
	line-height:156%;
	page-break-after:avoid;
	font-size:14.0pt;
	font-family:宋体;
	font-weight:bold;}
h6
	{mso-style-link:"标题 6 Char";
	margin-top:12.0pt;
	margin-right:0cm;
	margin-bottom:3.2pt;
	margin-left:43.2pt;
	text-align:justify;
	text-justify:inter-ideograph;
	text-indent:-43.2pt;
	line-height:133%;
	page-break-after:avoid;
	font-size:12.0pt;
	font-family:"Arial","sans-serif";
	font-weight:bold;}
p.MsoHeading7, li.MsoHeading7, div.MsoHeading7
	{mso-style-link:"标题 7 Char";
	margin-top:12.0pt;
	margin-right:0cm;
	margin-bottom:3.2pt;
	margin-left:50.4pt;
	text-align:justify;
	text-justify:inter-ideograph;
	text-indent:-50.4pt;
	line-height:133%;
	page-break-after:avoid;
	font-size:12.0pt;
	font-family:宋体;
	font-weight:bold;}
p.MsoHeading8, li.MsoHeading8, div.MsoHeading8
	{mso-style-link:"标题 8 Char";
	margin-top:12.0pt;
	margin-right:0cm;
	margin-bottom:3.2pt;
	margin-left:57.6pt;
	text-align:justify;
	text-justify:inter-ideograph;
	text-indent:-72.0pt;
	line-height:133%;
	page-break-after:avoid;
	font-size:12.0pt;
	font-family:"Arial","sans-serif";}
p.MsoHeading9, li.MsoHeading9, div.MsoHeading9
	{mso-style-link:"标题 9 Char";
	margin-top:12.0pt;
	margin-right:0cm;
	margin-bottom:3.2pt;
	margin-left:64.8pt;
	text-align:justify;
	text-justify:inter-ideograph;
	text-indent:-79.2pt;
	line-height:133%;
	page-break-after:avoid;
	font-size:10.5pt;
	font-family:"Arial","sans-serif";}
p.MsoIndex1, li.MsoIndex1, div.MsoIndex1
	{margin-top:0cm;
	margin-right:0cm;
	margin-bottom:0cm;
	margin-left:10.5pt;
	margin-bottom:.0001pt;
	text-align:justify;
	text-justify:inter-ideograph;
	text-indent:-10.5pt;
	font-size:10.5pt;
	font-family:宋体;}
p.MsoIndex2, li.MsoIndex2, div.MsoIndex2
	{margin-top:0cm;
	margin-right:0cm;
	margin-bottom:0cm;
	margin-left:21.0pt;
	margin-bottom:.0001pt;
	text-align:justify;
	text-justify:inter-ideograph;
	text-indent:-10.5pt;
	font-size:10.5pt;
	font-family:宋体;}
p.MsoIndex3, li.MsoIndex3, div.MsoIndex3
	{margin-top:0cm;
	margin-right:0cm;
	margin-bottom:0cm;
	margin-left:31.5pt;
	margin-bottom:.0001pt;
	text-align:justify;
	text-justify:inter-ideograph;
	text-indent:-10.5pt;
	font-size:10.5pt;
	font-family:宋体;}
p.MsoIndex4, li.MsoIndex4, div.MsoIndex4
	{margin-top:0cm;
	margin-right:0cm;
	margin-bottom:0cm;
	margin-left:42.0pt;
	margin-bottom:.0001pt;
	text-align:justify;
	text-justify:inter-ideograph;
	text-indent:-10.5pt;
	font-size:10.5pt;
	font-family:宋体;}
p.MsoIndex5, li.MsoIndex5, div.MsoIndex5
	{margin-top:0cm;
	margin-right:0cm;
	margin-bottom:0cm;
	margin-left:52.5pt;
	margin-bottom:.0001pt;
	text-align:justify;
	text-justify:inter-ideograph;
	text-indent:-10.5pt;
	font-size:10.5pt;
	font-family:宋体;}
p.MsoIndex6, li.MsoIndex6, div.MsoIndex6
	{margin-top:0cm;
	margin-right:0cm;
	margin-bottom:0cm;
	margin-left:63.0pt;
	margin-bottom:.0001pt;
	text-align:justify;
	text-justify:inter-ideograph;
	text-indent:-10.5pt;
	font-size:10.5pt;
	font-family:宋体;}
p.MsoIndex7, li.MsoIndex7, div.MsoIndex7
	{margin-top:0cm;
	margin-right:0cm;
	margin-bottom:0cm;
	margin-left:73.5pt;
	margin-bottom:.0001pt;
	text-align:justify;
	text-justify:inter-ideograph;
	text-indent:-10.5pt;
	font-size:10.5pt;
	font-family:宋体;}
p.MsoIndex8, li.MsoIndex8, div.MsoIndex8
	{margin-top:0cm;
	margin-right:0cm;
	margin-bottom:0cm;
	margin-left:84.0pt;
	margin-bottom:.0001pt;
	text-align:justify;
	text-justify:inter-ideograph;
	text-indent:-10.5pt;
	font-size:10.5pt;
	font-family:宋体;}
p.MsoIndex9, li.MsoIndex9, div.MsoIndex9
	{margin-top:0cm;
	margin-right:0cm;
	margin-bottom:0cm;
	margin-left:94.5pt;
	margin-bottom:.0001pt;
	text-align:justify;
	text-justify:inter-ideograph;
	text-indent:-10.5pt;
	font-size:10.5pt;
	font-family:宋体;}
p.MsoToc1, li.MsoToc1, div.MsoToc1
	{margin:0cm;
	margin-bottom:.0001pt;
	text-align:justify;
	text-justify:inter-ideograph;
	font-size:10.5pt;
	font-family:宋体;
	font-weight:bold;}
p.MsoToc2, li.MsoToc2, div.MsoToc2
	{margin-top:0cm;
	margin-right:0cm;
	margin-bottom:0cm;
	margin-left:21.0pt;
	margin-bottom:.0001pt;
	text-align:justify;
	text-justify:inter-ideograph;
	font-size:10.5pt;
	font-family:宋体;}
p.MsoToc3, li.MsoToc3, div.MsoToc3
	{margin-top:0cm;
	margin-right:0cm;
	margin-bottom:0cm;
	margin-left:42.0pt;
	margin-bottom:.0001pt;
	text-align:justify;
	text-justify:inter-ideograph;
	font-size:10.5pt;
	font-family:宋体;}
p.MsoToc4, li.MsoToc4, div.MsoToc4
	{margin-top:0cm;
	margin-right:0cm;
	margin-bottom:0cm;
	margin-left:31.5pt;
	margin-bottom:.0001pt;
	font-size:9.0pt;
	font-family:宋体;}
p.MsoToc5, li.MsoToc5, div.MsoToc5
	{margin-top:0cm;
	margin-right:0cm;
	margin-bottom:0cm;
	margin-left:42.0pt;
	margin-bottom:.0001pt;
	font-size:9.0pt;
	font-family:宋体;}
p.MsoToc6, li.MsoToc6, div.MsoToc6
	{margin-top:0cm;
	margin-right:0cm;
	margin-bottom:0cm;
	margin-left:52.5pt;
	margin-bottom:.0001pt;
	font-size:9.0pt;
	font-family:宋体;}
p.MsoToc7, li.MsoToc7, div.MsoToc7
	{margin-top:0cm;
	margin-right:0cm;
	margin-bottom:0cm;
	margin-left:63.0pt;
	margin-bottom:.0001pt;
	font-size:9.0pt;
	font-family:宋体;}
p.MsoToc8, li.MsoToc8, div.MsoToc8
	{margin-top:0cm;
	margin-right:0cm;
	margin-bottom:0cm;
	margin-left:73.5pt;
	margin-bottom:.0001pt;
	font-size:9.0pt;
	font-family:宋体;}
p.MsoToc9, li.MsoToc9, div.MsoToc9
	{margin-top:0cm;
	margin-right:0cm;
	margin-bottom:0cm;
	margin-left:84.0pt;
	margin-bottom:.0001pt;
	font-size:9.0pt;
	font-family:宋体;}
p.MsoFootnoteText, li.MsoFootnoteText, div.MsoFootnoteText
	{mso-style-link:"脚注文本 Char";
	margin:0cm;
	margin-bottom:.0001pt;
	layout-grid-mode:char;
	font-size:9.0pt;
	font-family:宋体;}
p.MsoCommentText, li.MsoCommentText, div.MsoCommentText
	{mso-style-link:"批注文字 Char";
	margin:0cm;
	margin-bottom:.0001pt;
	font-size:10.5pt;
	font-family:宋体;}
p.MsoHeader, li.MsoHeader, div.MsoHeader
	{mso-style-link:"页眉 Char";
	margin:0cm;
	margin-bottom:.0001pt;
	text-align:center;
	layout-grid-mode:char;
	border:none;
	padding:0cm;
	font-size:9.0pt;
	font-family:宋体;}
p.MsoFooter, li.MsoFooter, div.MsoFooter
	{mso-style-link:"页脚 Char";
	margin:0cm;
	margin-bottom:.0001pt;
	layout-grid-mode:char;
	font-size:9.0pt;
	font-family:宋体;}
p.MsoIndexHeading, li.MsoIndexHeading, div.MsoIndexHeading
	{mso-style-name:"索引标题\,索引类目\,索引类目1\,索引类目2";
	margin:0cm;
	margin-bottom:.0001pt;
	text-align:justify;
	text-justify:inter-ideograph;
	font-size:10.5pt;
	font-family:宋体;}
p.MsoCaption, li.MsoCaption, div.MsoCaption
	{margin:0cm;
	margin-bottom:.0001pt;
	text-align:justify;
	text-justify:inter-ideograph;
	font-size:10.5pt;
	font-family:"Arial","sans-serif";}
p.MsoTof, li.MsoTof, div.MsoTof
	{margin-top:0cm;
	margin-right:0cm;
	margin-bottom:0cm;
	margin-left:42.0pt;
	margin-bottom:.0001pt;
	text-align:justify;
	text-justify:inter-ideograph;
	text-indent:-21.0pt;
	font-size:10.5pt;
	font-family:宋体;}
span.MsoFootnoteReference
	{vertical-align:super;}
p.MsoList, li.MsoList, div.MsoList
	{margin-top:0cm;
	margin-right:0cm;
	margin-bottom:0cm;
	margin-left:21.0pt;
	margin-bottom:.0001pt;
	text-align:center;
	text-indent:-21.0pt;
	font-size:10.5pt;
	font-family:宋体;}
p.MsoList2, li.MsoList2, div.MsoList2
	{margin:0cm;
	margin-bottom:.0001pt;
	text-align:justify;
	text-justify:inter-ideograph;
	font-size:10.5pt;
	font-family:宋体;}
p.MsoList4, li.MsoList4, div.MsoList4
	{margin:0cm;
	margin-bottom:.0001pt;
	text-align:center;
	font-size:10.5pt;
	font-family:宋体;}
p.MsoDate, li.MsoDate, div.MsoDate
	{mso-style-link:"日期 Char";
	margin-top:0cm;
	margin-right:0cm;
	margin-bottom:0cm;
	margin-left:5.0pt;
	margin-bottom:.0001pt;
	text-align:justify;
	text-justify:inter-ideograph;
	font-size:10.5pt;
	font-family:宋体;}
a:link, span.MsoHyperlink
	{mso-style-name:"超链接\,超级链接";
	color:blue;
	text-decoration:underline;}
a:visited, span.MsoHyperlinkFollowed
	{color:purple;
	text-decoration:underline;}
p
	{mso-style-name:"普通\(网站\)\,普通 \(Web\)\,普通 \(Web\)1\,普通 \(Web\)2\,普通 \(Web\)3";
	margin-right:0cm;
	margin-left:0cm;
	font-size:12.0pt;
	font-family:宋体;}
pre
	{mso-style-name:"HTML 预设格式\,HTML 预先格式化\,HTML 预先格式化1\,HTML 预先格式化2\,HTML 预先格式化3";
	mso-style-link:"HTML 预设格式 Char\,HTML 预先格式化 Char\,HTML 预先格式化1 Char\,HTML 预先格式化2 Char\,HTML 预先格式化3 Char";
	margin:0cm;
	margin-bottom:.0001pt;
	font-size:12.0pt;
	font-family:宋体;}
tt
	{font-family:黑体;}
p.MsoCommentSubject, li.MsoCommentSubject, div.MsoCommentSubject
	{mso-style-link:"批注主题 Char";
	margin:0cm;
	margin-bottom:.0001pt;
	font-size:10.5pt;
	font-family:宋体;
	font-weight:bold;}
p.MsoAcetate, li.MsoAcetate, div.MsoAcetate
	{mso-style-link:"批注框文本 Char";
	margin:0cm;
	margin-bottom:.0001pt;
	text-align:justify;
	text-justify:inter-ideograph;
	font-size:9.0pt;
	font-family:宋体;}
p.1, li.1, div.1
	{mso-style-name:样式1;
	margin-top:0cm;
	margin-right:0cm;
	margin-bottom:0cm;
	margin-left:21.0pt;
	margin-bottom:.0001pt;
	text-align:center;
	text-indent:-21.0pt;
	font-size:10.5pt;
	font-family:宋体;}
p.a, li.a, div.a
	{mso-style-name:代码程序;
	mso-style-link:"代码程序 Char";
	margin:0cm;
	margin-bottom:.0001pt;
	font-size:10.0pt;
	font-family:宋体;}
span.Char
	{mso-style-name:"代码程序 Char";
	mso-style-link:代码程序;
	font-family:宋体;}
p.a0, li.a0, div.a0
	{mso-style-name:图说明;
	mso-style-link:"图说明 Char";
	margin:0cm;
	margin-bottom:.0001pt;
	text-align:center;
	font-size:10.5pt;
	font-family:宋体;}
span.Char0
	{mso-style-name:"图说明 Char";
	mso-style-link:图说明;
	font-family:宋体;}
p.0, li.0, div.0
	{mso-style-name:封面0;
	margin:0cm;
	margin-bottom:.0001pt;
	text-align:center;
	font-size:36.0pt;
	font-family:宋体;
	font-weight:bold;}
p.10, li.10, div.10
	{mso-style-name:封面1;
	margin:0cm;
	margin-bottom:.0001pt;
	text-align:center;
	font-size:18.0pt;
	font-family:宋体;
	font-weight:bold;}
p.11, li.11, div.11
	{mso-style-name:非标题1;
	margin-top:7.8pt;
	margin-right:0cm;
	margin-bottom:7.8pt;
	margin-left:0cm;
	text-align:center;
	font-size:22.0pt;
	font-family:宋体;
	font-weight:bold;}
p.a1, li.a1, div.a1
	{mso-style-name:文本居中;
	margin:0cm;
	margin-bottom:.0001pt;
	text-align:center;
	font-size:10.5pt;
	font-family:宋体;}
p.3CharChar, li.3CharChar, div.3CharChar
	{mso-style-name:"图中文字3 Char Char";
	mso-style-link:"图中文字3 Char Char Char";
	margin:0cm;
	margin-bottom:.0001pt;
	text-align:center;
	line-height:9.0pt;
	font-size:8.0pt;
	font-family:宋体;}
span.3CharCharChar
	{mso-style-name:"图中文字3 Char Char Char";
	mso-style-link:"图中文字3 Char Char";
	font-family:宋体;}
p.post, li.post, div.post
	{mso-style-name:邮件post;
	margin:0cm;
	margin-bottom:.0001pt;
	text-align:right;
	line-height:11.0pt;
	font-size:10.5pt;
	font-family:宋体;}
p.3, li.3, div.3
	{mso-style-name:图中字体3;
	margin:0cm;
	margin-bottom:.0001pt;
	text-align:justify;
	text-justify:inter-ideograph;
	font-size:10.5pt;
	font-family:宋体;}
span.3CharChar1CharCharChar
	{mso-style-name:"图中文字3 Char Char1 Char Char Char";
	font-family:宋体;}
span.3CharChar1CharChar
	{mso-style-name:"图中文字3 Char Char1 Char Char";
	font-family:宋体;}
p.5Char, li.5Char, div.5Char
	{mso-style-name:"图中文字5号 Char";
	mso-style-link:"图中文字5号 Char Char";
	margin:0cm;
	margin-bottom:.0001pt;
	text-align:center;
	font-size:10.5pt;
	font-family:宋体;}
span.5CharChar
	{mso-style-name:"图中文字5号 Char Char";
	mso-style-link:"图中文字5号 Char";
	font-family:宋体;}
p.5CharChar0, li.5CharChar0, div.5CharChar0
	{mso-style-name:"图中文字小5号 Char Char";
	mso-style-link:"图中文字小5号 Char Char Char";
	margin:0cm;
	margin-bottom:.0001pt;
	text-align:center;
	font-size:9.0pt;
	font-family:宋体;}
span.5CharCharChar
	{mso-style-name:"图中文字小5号 Char Char Char";
	mso-style-link:"图中文字小5号 Char Char";
	font-family:宋体;}
p.5Char0, li.5Char0, div.5Char0
	{mso-style-name:"图中文字小5号 Char";
	margin:0cm;
	margin-bottom:.0001pt;
	text-align:center;
	font-size:9.0pt;
	font-family:宋体;}
p.5, li.5, div.5
	{mso-style-name:图中文字小5号;
	margin:0cm;
	margin-bottom:.0001pt;
	text-align:center;
	layout-grid-mode:char;
	font-size:9.0pt;
	font-family:宋体;}
p.2, li.2, div.2
	{mso-style-name:代码程序2;
	margin:0cm;
	margin-bottom:.0001pt;
	font-size:10.0pt;
	font-family:宋体;}
p.20, li.20, div.20
	{mso-style-name:图说明2;
	margin:0cm;
	margin-bottom:.0001pt;
	text-align:center;
	font-size:10.5pt;
	font-family:宋体;}
p.21, li.21, div.21
	{mso-style-name:文本居中2;
	margin:0cm;
	margin-bottom:.0001pt;
	text-align:center;
	font-size:10.5pt;
	font-family:宋体;}
p.3CharCharCharCharChar, li.3CharCharCharCharChar, div.3CharCharCharCharChar
	{mso-style-name:"图中文字3 Char Char Char Char Char";
	mso-style-link:"图中文字3 Char Char Char Char Char Char";
	margin:0cm;
	margin-bottom:.0001pt;
	text-align:center;
	line-height:9.0pt;
	font-size:8.0pt;
	font-family:宋体;}
span.3CharCharCharCharCharChar
	{mso-style-name:"图中文字3 Char Char Char Char Char Char";
	mso-style-link:"图中文字3 Char Char Char Char Char";
	font-family:宋体;}
p.a2, li.a2, div.a2
	{mso-style-name:图居中;
	margin:0cm;
	margin-bottom:.0001pt;
	text-align:center;
	font-size:10.5pt;
	font-family:宋体;}
p.110, li.110, div.110
	{mso-style-name:"样式 标题 1 + 居中1";
	margin-right:0cm;
	margin-left:0cm;
	text-align:center;
	page-break-after:avoid;
	font-size:22.0pt;
	font-family:宋体;
	font-weight:bold;}
span.1Char
	{mso-style-name:"标题 1 Char";
	mso-style-link:"标题 1";
	font-weight:bold;}
p.22, li.22, div.22
	{mso-style-name:"样式 列表 2 + 居中";
	margin:0cm;
	margin-bottom:.0001pt;
	text-align:center;
	font-size:10.5pt;
	font-family:宋体;}
p.23, li.23, div.23
	{mso-style-name:列表2;
	margin:0cm;
	margin-bottom:.0001pt;
	text-align:center;
	font-size:10.5pt;
	font-family:宋体;}
p.50, li.50, div.50
	{mso-style-name:图中文字5号;
	margin:0cm;
	margin-bottom:.0001pt;
	text-align:center;
	font-size:10.5pt;
	font-family:宋体;}
p.111, li.111, div.111
	{mso-style-name:样式11;
	margin-top:0cm;
	margin-right:0cm;
	margin-bottom:0cm;
	margin-left:21.0pt;
	margin-bottom:.0001pt;
	text-align:center;
	text-indent:-21.0pt;
	font-size:10.5pt;
	font-family:宋体;}
p.12, li.12, div.12
	{mso-style-name:代码程序1;
	margin:0cm;
	margin-bottom:.0001pt;
	font-size:10.0pt;
	font-family:宋体;}
p.13, li.13, div.13
	{mso-style-name:图说明1;
	margin:0cm;
	margin-bottom:.0001pt;
	text-align:center;
	font-size:10.5pt;
	font-family:宋体;}
p.01, li.01, div.01
	{mso-style-name:封面01;
	margin:0cm;
	margin-bottom:.0001pt;
	text-align:center;
	font-size:36.0pt;
	font-family:宋体;
	font-weight:bold;}
p.112, li.112, div.112
	{mso-style-name:封面11;
	margin:0cm;
	margin-bottom:.0001pt;
	text-align:center;
	font-size:18.0pt;
	font-family:宋体;
	font-weight:bold;}
p.113, li.113, div.113
	{mso-style-name:非标题11;
	margin-top:7.8pt;
	margin-right:0cm;
	margin-bottom:7.8pt;
	margin-left:0cm;
	text-align:center;
	font-size:22.0pt;
	font-family:宋体;
	font-weight:bold;}
p.14, li.14, div.14
	{mso-style-name:文本居中1;
	margin:0cm;
	margin-bottom:.0001pt;
	text-align:center;
	font-size:10.5pt;
	font-family:宋体;}
p.3Char1, li.3Char1, div.3Char1
	{mso-style-name:"图中文字3 Char1";
	margin:0cm;
	margin-bottom:.0001pt;
	text-align:center;
	line-height:9.0pt;
	font-size:8.0pt;
	font-family:宋体;}
p.post1, li.post1, div.post1
	{mso-style-name:邮件post1;
	margin:0cm;
	margin-bottom:.0001pt;
	text-align:right;
	line-height:11.0pt;
	font-size:10.5pt;
	font-family:宋体;}
p.31, li.31, div.31
	{mso-style-name:图中字体31;
	margin:0cm;
	margin-bottom:.0001pt;
	text-align:justify;
	text-justify:inter-ideograph;
	font-size:10.5pt;
	font-family:宋体;}
p.5Char1, li.5Char1, div.5Char1
	{mso-style-name:"图中文字5号 Char1";
	margin:0cm;
	margin-bottom:.0001pt;
	text-align:center;
	font-size:10.5pt;
	font-family:宋体;}
p.5CharChar1, li.5CharChar1, div.5CharChar1
	{mso-style-name:"图中文字小5号 Char Char1";
	margin:0cm;
	margin-bottom:.0001pt;
	text-align:center;
	font-size:9.0pt;
	font-family:宋体;}
p.5Char10, li.5Char10, div.5Char10
	{mso-style-name:"图中文字小5号 Char1";
	margin:0cm;
	margin-bottom:.0001pt;
	text-align:center;
	font-size:9.0pt;
	font-family:宋体;}
p.51, li.51, div.51
	{mso-style-name:图中文字小5号1;
	margin:0cm;
	margin-bottom:.0001pt;
	text-align:center;
	font-size:9.0pt;
	font-family:宋体;}
p.120, li.120, div.120
	{mso-style-name:样式12;
	margin-top:0cm;
	margin-right:0cm;
	margin-bottom:0cm;
	margin-left:21.0pt;
	margin-bottom:.0001pt;
	text-align:center;
	text-indent:-21.0pt;
	font-size:10.5pt;
	font-family:宋体;}
p.02, li.02, div.02
	{mso-style-name:封面02;
	margin:0cm;
	margin-bottom:.0001pt;
	text-align:center;
	font-size:36.0pt;
	font-family:宋体;
	font-weight:bold;}
p.121, li.121, div.121
	{mso-style-name:封面12;
	margin:0cm;
	margin-bottom:.0001pt;
	text-align:center;
	font-size:18.0pt;
	font-family:宋体;
	font-weight:bold;}
p.122, li.122, div.122
	{mso-style-name:非标题12;
	margin-top:7.8pt;
	margin-right:0cm;
	margin-bottom:7.8pt;
	margin-left:0cm;
	text-align:center;
	font-size:22.0pt;
	font-family:宋体;
	font-weight:bold;}
p.3Char2, li.3Char2, div.3Char2
	{mso-style-name:"图中文字3 Char2";
	margin:0cm;
	margin-bottom:.0001pt;
	text-align:center;
	line-height:9.0pt;
	font-size:8.0pt;
	font-family:宋体;}
p.post2, li.post2, div.post2
	{mso-style-name:邮件post2;
	margin:0cm;
	margin-bottom:.0001pt;
	text-align:right;
	line-height:11.0pt;
	font-size:10.5pt;
	font-family:宋体;}
p.32, li.32, div.32
	{mso-style-name:图中字体32;
	margin:0cm;
	margin-bottom:.0001pt;
	text-align:justify;
	text-justify:inter-ideograph;
	font-size:10.5pt;
	font-family:宋体;}
p.5Char2, li.5Char2, div.5Char2
	{mso-style-name:"图中文字小5号 Char2";
	margin:0cm;
	margin-bottom:.0001pt;
	text-align:center;
	font-size:9.0pt;
	font-family:宋体;}
p.52, li.52, div.52
	{mso-style-name:图中文字小5号2;
	margin:0cm;
	margin-bottom:.0001pt;
	text-align:center;
	font-size:9.0pt;
	font-family:宋体;}
p.3CharCharCharChar, li.3CharCharCharChar, div.3CharCharCharChar
	{mso-style-name:"图中文字3 Char Char Char Char";
	margin:0cm;
	margin-bottom:.0001pt;
	text-align:center;
	line-height:9.0pt;
	font-size:8.0pt;
	font-family:宋体;}
p.130, li.130, div.130
	{mso-style-name:样式13;
	margin-top:0cm;
	margin-right:0cm;
	margin-bottom:0cm;
	margin-left:21.0pt;
	margin-bottom:.0001pt;
	text-align:center;
	text-indent:-21.0pt;
	font-size:10.5pt;
	font-family:宋体;}
p.30, li.30, div.30
	{mso-style-name:代码程序3;
	margin:0cm;
	margin-bottom:.0001pt;
	font-size:10.0pt;
	font-family:宋体;}
p.03, li.03, div.03
	{mso-style-name:封面03;
	margin:0cm;
	margin-bottom:.0001pt;
	text-align:center;
	font-size:36.0pt;
	font-family:宋体;
	font-weight:bold;}
p.131, li.131, div.131
	{mso-style-name:封面13;
	margin:0cm;
	margin-bottom:.0001pt;
	text-align:center;
	font-size:18.0pt;
	font-family:宋体;
	font-weight:bold;}
p.132, li.132, div.132
	{mso-style-name:非标题13;
	margin-top:7.8pt;
	margin-right:0cm;
	margin-bottom:7.8pt;
	margin-left:0cm;
	text-align:center;
	font-size:22.0pt;
	font-family:宋体;
	font-weight:bold;}
p.33, li.33, div.33
	{mso-style-name:文本居中3;
	margin:0cm;
	margin-bottom:.0001pt;
	text-align:center;
	font-size:10.5pt;
	font-family:宋体;}
p.3Char3, li.3Char3, div.3Char3
	{mso-style-name:"图中文字3 Char3";
	margin:0cm;
	margin-bottom:.0001pt;
	text-align:center;
	line-height:9.0pt;
	font-size:8.0pt;
	font-family:宋体;}
p.post3, li.post3, div.post3
	{mso-style-name:邮件post3;
	margin:0cm;
	margin-bottom:.0001pt;
	text-align:right;
	line-height:11.0pt;
	font-size:10.5pt;
	font-family:宋体;}
p.330, li.330, div.330
	{mso-style-name:图中字体33;
	margin:0cm;
	margin-bottom:.0001pt;
	text-align:justify;
	text-justify:inter-ideograph;
	font-size:10.5pt;
	font-family:宋体;}
p.5Char20, li.5Char20, div.5Char20
	{mso-style-name:"图中文字5号 Char2";
	margin:0cm;
	margin-bottom:.0001pt;
	text-align:center;
	font-size:10.5pt;
	font-family:宋体;}
p.5CharChar2, li.5CharChar2, div.5CharChar2
	{mso-style-name:"图中文字小5号 Char Char2";
	margin:0cm;
	margin-bottom:.0001pt;
	text-align:center;
	font-size:9.0pt;
	font-family:宋体;}
p.5Char3, li.5Char3, div.5Char3
	{mso-style-name:"图中文字小5号 Char3";
	margin:0cm;
	margin-bottom:.0001pt;
	text-align:center;
	font-size:9.0pt;
	font-family:宋体;}
p.53, li.53, div.53
	{mso-style-name:图中文字小5号3;
	margin:0cm;
	margin-bottom:.0001pt;
	text-align:center;
	font-size:9.0pt;
	font-family:宋体;}
p.3Char, li.3Char, div.3Char
	{mso-style-name:"图中文字3 Char";
	mso-style-link:"图中文字3 Char Char5";
	margin:0cm;
	margin-bottom:.0001pt;
	text-align:center;
	line-height:9.0pt;
	font-size:8.0pt;
	font-family:宋体;}
span.3CharChar5
	{mso-style-name:"图中文字3 Char Char5";
	mso-style-link:"图中文字3 Char";
	font-family:宋体;}
p.54, li.54, div.54
	{mso-style-name:图中文字小5紧密;
	margin:0cm;
	margin-bottom:.0001pt;
	line-height:9.0pt;
	text-autospace:ideograph-numeric;
	font-size:9.0pt;
	font-family:宋体;}
p.24, li.24, div.24
	{mso-style-name:居中2号粗宋体;
	margin:0cm;
	margin-bottom:.0001pt;
	text-align:center;
	font-size:22.0pt;
	font-family:宋体;
	font-weight:bold;}
p.15, li.15, div.15
	{mso-style-name:"样式 标题 1 + 居中";
	margin-top:17.0pt;
	margin-right:0cm;
	margin-bottom:16.5pt;
	margin-left:0cm;
	text-align:center;
	page-break-after:avoid;
	font-size:22.0pt;
	font-family:宋体;
	font-weight:bold;}
p.25, li.25, div.25
	{mso-style-name:"样式 标题 2 + 行距\: 单倍行距";
	margin-top:13.0pt;
	margin-right:0cm;
	margin-bottom:13.0pt;
	margin-left:28.9pt;
	text-align:justify;
	text-justify:inter-ideograph;
	text-indent:-28.9pt;
	page-break-after:avoid;
	font-size:16.0pt;
	font-family:"Arial","sans-serif";
	font-weight:bold;}
span.2Char
	{mso-style-name:"标题 2 Char";
	mso-style-link:"标题 2";
	font-family:"Arial","sans-serif";
	font-weight:bold;}
p.34, li.34, div.34
	{mso-style-name:列表3;
	margin:0cm;
	margin-bottom:.0001pt;
	text-align:center;
	font-size:10.5pt;
	font-family:宋体;}
p.35, li.35, div.35
	{mso-style-name:表3;
	margin:0cm;
	margin-bottom:.0001pt;
	text-align:center;
	font-size:10.5pt;
	font-family:宋体;}
p.4, li.4, div.4
	{mso-style-name:图说明4;
	margin:0cm;
	margin-bottom:.0001pt;
	text-align:center;
	font-size:10.5pt;
	font-family:宋体;}
p.40, li.40, div.40
	{mso-style-name:列表4;
	margin-top:0cm;
	margin-right:0cm;
	margin-bottom:0cm;
	margin-left:21.0pt;
	margin-bottom:.0001pt;
	text-align:center;
	text-indent:-21.0pt;
	font-size:10.5pt;
	font-family:宋体;}
p.41, li.41, div.41
	{mso-style-name:表4;
	margin:0cm;
	margin-bottom:.0001pt;
	text-align:center;
	font-size:10.5pt;
	font-family:宋体;}
p.55, li.55, div.55
	{mso-style-name:图说明5;
	margin:0cm;
	margin-bottom:.0001pt;
	text-align:center;
	font-size:10.5pt;
	font-family:宋体;}
p.56, li.56, div.56
	{mso-style-name:列表5;
	margin:0cm;
	margin-bottom:.0001pt;
	text-align:center;
	font-size:10.5pt;
	font-family:宋体;}
p.57, li.57, div.57
	{mso-style-name:表5;
	margin:0cm;
	margin-bottom:.0001pt;
	text-align:center;
	font-size:10.5pt;
	font-family:宋体;}
p.6, li.6, div.6
	{mso-style-name:列表6;
	margin:0cm;
	margin-bottom:.0001pt;
	text-align:center;
	font-size:10.5pt;
	font-family:宋体;}
p.60, li.60, div.60
	{mso-style-name:表6;
	margin:0cm;
	margin-bottom:.0001pt;
	text-align:center;
	font-size:10.5pt;
	font-family:宋体;}
p.61, li.61, div.61
	{mso-style-name:图说明6;
	margin:0cm;
	margin-bottom:.0001pt;
	text-align:center;
	font-size:10.5pt;
	font-family:宋体;}
p.7, li.7, div.7
	{mso-style-name:列表7;
	margin:0cm;
	margin-bottom:.0001pt;
	text-align:center;
	font-size:10.5pt;
	font-family:宋体;}
p.70, li.70, div.70
	{mso-style-name:图说明7;
	margin:0cm;
	margin-bottom:.0001pt;
	text-align:center;
	font-size:10.5pt;
	font-family:宋体;}
p.71, li.71, div.71
	{mso-style-name:表7;
	margin:0cm;
	margin-bottom:.0001pt;
	text-align:center;
	font-size:10.5pt;
	font-family:宋体;}
p.8, li.8, div.8
	{mso-style-name:列表8;
	margin:0cm;
	margin-bottom:.0001pt;
	text-align:center;
	font-size:10.5pt;
	font-family:宋体;}
p.9, li.9, div.9
	{mso-style-name:列表9;
	margin:0cm;
	margin-bottom:.0001pt;
	text-align:center;
	font-size:10.5pt;
	font-family:宋体;}
p.90, li.90, div.90
	{mso-style-name:图说明9;
	margin:0cm;
	margin-bottom:.0001pt;
	text-align:center;
	font-size:10.5pt;
	font-family:宋体;}
p.100, li.100, div.100
	{mso-style-name:列表10;
	margin:0cm;
	margin-bottom:.0001pt;
	text-align:center;
	font-size:10.5pt;
	font-family:宋体;}
p.101, li.101, div.101
	{mso-style-name:图说明10;
	margin:0cm;
	margin-bottom:.0001pt;
	text-align:center;
	font-size:10.5pt;
	font-family:宋体;}
p.114, li.114, div.114
	{mso-style-name:列表11;
	margin:0cm;
	margin-bottom:.0001pt;
	text-align:center;
	font-size:10.5pt;
	font-family:宋体;}
p.115, li.115, div.115
	{mso-style-name:图说明11;
	margin:0cm;
	margin-bottom:.0001pt;
	text-align:center;
	font-size:10.5pt;
	font-family:宋体;}
p.116, li.116, div.116
	{mso-style-name:表11;
	margin:0cm;
	margin-bottom:.0001pt;
	text-align:center;
	font-size:10.5pt;
	font-family:宋体;}
p.123, li.123, div.123
	{mso-style-name:列表12;
	margin:0cm;
	margin-bottom:.0001pt;
	text-align:center;
	font-size:10.5pt;
	font-family:宋体;}
p.124, li.124, div.124
	{mso-style-name:图说明12;
	margin:0cm;
	margin-bottom:.0001pt;
	text-align:center;
	font-size:10.5pt;
	font-family:宋体;}
p.133, li.133, div.133
	{mso-style-name:图说明13;
	mso-style-link:"图说明13 Char";
	margin:0cm;
	margin-bottom:.0001pt;
	text-align:center;
	font-size:10.5pt;
	font-family:宋体;}
span.13Char
	{mso-style-name:"图说明13 Char";
	mso-style-link:图说明13;
	font-family:宋体;}
p.134, li.134, div.134
	{mso-style-name:列表13;
	margin:0cm;
	margin-bottom:.0001pt;
	text-align:center;
	font-size:10.5pt;
	font-family:宋体;}
p.26, li.26, div.26
	{mso-style-name:附录2;
	margin-top:13.0pt;
	margin-right:0cm;
	margin-bottom:13.0pt;
	margin-left:0cm;
	text-align:justify;
	text-justify:inter-ideograph;
	page-break-after:avoid;
	font-size:16.0pt;
	font-family:"Arial","sans-serif";
	font-weight:bold;}
p.36, li.36, div.36
	{mso-style-name:附录3;
	margin:0cm;
	margin-bottom:.0001pt;
	text-align:justify;
	text-justify:inter-ideograph;
	page-break-after:avoid;
	font-size:14.0pt;
	font-family:"Arial","sans-serif";
	font-weight:bold;}
span.3Char0
	{mso-style-name:"标题 3 Char";
	mso-style-link:"标题 3";
	font-family:"Arial","sans-serif";
	font-weight:bold;}
p.16, li.16, div.16
	{mso-style-name:附录1;
	margin-top:17.0pt;
	margin-right:0cm;
	margin-bottom:16.5pt;
	margin-left:0cm;
	text-align:center;
	page-break-after:avoid;
	font-size:22.0pt;
	font-family:宋体;
	font-weight:bold;}
p.17, li.17, div.17
	{mso-style-name:附录表1;
	margin:0cm;
	margin-bottom:.0001pt;
	text-align:center;
	font-size:10.5pt;
	font-family:宋体;}
p.42, li.42, div.42
	{mso-style-name:附录4;
	margin:0cm;
	margin-bottom:.0001pt;
	text-align:justify;
	text-justify:inter-ideograph;
	page-break-after:avoid;
	font-size:12.0pt;
	font-family:"Arial","sans-serif";
	font-weight:bold;}
span.4Char
	{mso-style-name:"标题 4 Char";
	mso-style-link:"标题 4";
	font-family:"Arial","sans-serif";
	font-weight:bold;}
p.a3, li.a3, div.a3
	{mso-style-name:附录图说明;
	margin:0cm;
	margin-bottom:.0001pt;
	text-align:center;
	font-size:10.5pt;
	font-family:宋体;}
p.27, li.27, div.27
	{mso-style-name:序标题2;
	margin-top:13.0pt;
	margin-right:0cm;
	margin-bottom:13.0pt;
	margin-left:28.8pt;
	text-align:justify;
	text-justify:inter-ideograph;
	text-indent:-28.8pt;
	page-break-after:avoid;
	font-size:16.0pt;
	font-family:"Arial","sans-serif";
	font-weight:bold;}
p.a4, li.a4, div.a4
	{mso-style-name:参考标题;
	margin-top:7.8pt;
	margin-right:0cm;
	margin-bottom:7.8pt;
	margin-left:0cm;
	text-align:center;
	page-break-after:avoid;
	font-size:22.0pt;
	font-family:宋体;
	font-weight:bold;}
p.18, li.18, div.18
	{mso-style-name:索引标题1;
	margin-top:7.8pt;
	margin-right:0cm;
	margin-bottom:7.8pt;
	margin-left:0cm;
	text-align:center;
	page-break-after:avoid;
	font-size:22.0pt;
	font-family:宋体;
	font-weight:bold;}
p.19, li.19, div.19
	{mso-style-name:列表1;
	margin-top:0cm;
	margin-right:0cm;
	margin-bottom:0cm;
	margin-left:21.25pt;
	margin-bottom:.0001pt;
	text-align:center;
	text-indent:-21.25pt;
	font-size:10.5pt;
	font-family:宋体;}
p.1a, li.1a, div.1a
	{mso-style-name:表1;
	margin-top:0cm;
	margin-right:0cm;
	margin-bottom:0cm;
	margin-left:21.25pt;
	margin-bottom:.0001pt;
	text-align:center;
	text-indent:-21.25pt;
	font-size:10.5pt;
	font-family:宋体;}
p.37, li.37, div.37
	{mso-style-name:图说明3;
	margin:0cm;
	margin-bottom:.0001pt;
	text-align:center;
	font-size:10.5pt;
	font-family:宋体;}
p.62, li.62, div.62
	{mso-style-name:表中字体6号;
	margin:0cm;
	margin-bottom:.0001pt;
	text-align:justify;
	text-justify:inter-ideograph;
	layout-grid-mode:char;
	font-size:7.5pt;
	font-family:宋体;}
p.a5, li.a5, div.a5
	{mso-style-name:正文代码;
	mso-style-link:"正文代码 Char";
	margin:0cm;
	margin-bottom:.0001pt;
	text-align:justify;
	text-justify:inter-ideograph;
	font-size:10.5pt;
	font-family:宋体;}
span.Char1
	{mso-style-name:"正文代码 Char";
	mso-style-link:正文代码;
	font-family:宋体;}
p.43, li.43, div.43
	{mso-style-name:"样式 标题 4 +";
	margin:0cm;
	margin-bottom:.0001pt;
	text-align:justify;
	text-justify:inter-ideograph;
	page-break-after:avoid;
	font-size:12.0pt;
	font-family:"Arial","sans-serif";
	font-weight:bold;}
p.140, li.140, div.140
	{mso-style-name:表14;
	margin-top:0cm;
	margin-right:0cm;
	margin-bottom:0cm;
	margin-left:21.25pt;
	margin-bottom:.0001pt;
	text-align:center;
	text-indent:-21.25pt;
	font-size:10.5pt;
	font-family:宋体;}
p.141, li.141, div.141
	{mso-style-name:图说明14;
	mso-style-link:"图说明14 Char";
	margin-top:0cm;
	margin-right:0cm;
	margin-bottom:0cm;
	margin-left:21.25pt;
	margin-bottom:.0001pt;
	text-align:center;
	text-indent:-21.25pt;
	font-size:10.5pt;
	font-family:宋体;}
span.14Char
	{mso-style-name:"图说明14 Char";
	mso-style-link:图说明14;
	font-family:宋体;}
p.a6, li.a6, div.a6
	{mso-style-name:文件目录表;
	margin:0cm;
	margin-bottom:.0001pt;
	text-align:justify;
	text-justify:inter-ideograph;
	font-size:10.5pt;
	font-family:宋体;}
p.a7, li.a7, div.a7
	{mso-style-name:"样式 正文 +";
	mso-style-link:"样式 正文 + Char";
	margin:0cm;
	margin-bottom:.0001pt;
	text-align:justify;
	text-justify:inter-ideograph;
	font-size:10.5pt;
	font-family:宋体;}
span.Char2
	{mso-style-name:"样式 正文 + Char";
	mso-style-link:"样式 正文 +";
	font-family:"Times New Roman","serif";}
p.a8, li.a8, div.a8
	{mso-style-name:表格题注;
	margin:0cm;
	margin-bottom:.0001pt;
	text-align:center;
	font-size:10.5pt;
	font-family:宋体;}
p.a9, li.a9, div.a9
	{mso-style-name:列表题注;
	margin:0cm;
	margin-bottom:.0001pt;
	text-align:center;
	font-size:10.5pt;
	font-family:"Arial","sans-serif";}
p.aa, li.aa, div.aa
	{mso-style-name:图题注;
	margin:0cm;
	margin-bottom:.0001pt;
	text-align:center;
	font-size:10.5pt;
	font-family:"Arial","sans-serif";}
p.ab, li.ab, div.ab
	{mso-style-name:程序题注;
	margin:0cm;
	margin-bottom:.0001pt;
	text-align:center;
	font-size:10.5pt;
	font-family:"Arial","sans-serif";}
p.ac, li.ac, div.ac
	{mso-style-name:框中文字;
	margin-top:0cm;
	margin-right:21.0pt;
	margin-bottom:0cm;
	margin-left:21.0pt;
	margin-bottom:.0001pt;
	text-align:justify;
	text-justify:inter-ideograph;
	border:none;
	padding:0cm;
	font-size:9.0pt;
	font-family:宋体;}
p.125, li.125, div.125
	{mso-style-name:"样式 标题 1 + 居中2";
	margin-top:17.0pt;
	margin-right:0cm;
	margin-bottom:16.5pt;
	margin-left:0cm;
	text-align:center;
	page-break-after:avoid;
	font-size:22.0pt;
	font-family:宋体;
	font-weight:bold;}
p.ad, li.ad, div.ad
	{mso-style-name:"样式 题注 + 宋体 五号 居中";
	margin:0cm;
	margin-bottom:.0001pt;
	text-align:center;
	font-size:10.5pt;
	font-family:黑体;}
p.1b, li.1b, div.1b
	{mso-style-name:序标题1;
	margin-top:17.0pt;
	margin-right:0cm;
	margin-bottom:16.5pt;
	margin-left:0cm;
	line-height:240%;
	page-break-after:avoid;
	font-size:16.0pt;
	font-family:宋体;
	font-weight:bold;}
p.38, li.38, div.38
	{mso-style-name:序标题3;
	margin:0cm;
	margin-bottom:.0001pt;
	text-align:justify;
	text-justify:inter-ideograph;
	page-break-after:avoid;
	font-size:12.0pt;
	font-family:方正小标宋简体;}
p.63, li.63, div.63
	{mso-style-name:表中文字6号;
	margin:0cm;
	margin-bottom:.0001pt;
	text-align:justify;
	text-justify:inter-ideograph;
	font-size:7.5pt;
	font-family:宋体;}
p.64, li.64, div.64
	{mso-style-name:图中文字6号左对齐;
	margin:0cm;
	margin-bottom:.0001pt;
	line-height:10.0pt;
	layout-grid-mode:char;
	font-size:7.5pt;
	font-family:宋体;}
p.65, li.65, div.65
	{mso-style-name:图中文字6号;
	mso-style-link:"图中文字6号 Char";
	margin:0cm;
	margin-bottom:.0001pt;
	text-align:center;
	line-height:10.0pt;
	layout-grid-mode:char;
	font-size:7.5pt;
	font-family:宋体;}
span.6Char
	{mso-style-name:"图中文字6号 Char";
	mso-style-link:图中文字6号;
	font-family:宋体;}
p.ae, li.ae, div.ae
	{mso-style-name:图标;
	margin:0cm;
	margin-bottom:.0001pt;
	text-align:justify;
	text-justify:inter-ideograph;
	font-size:10.5pt;
	font-family:宋体;}
p.28, li.28, div.28
	{mso-style-name:图标2;
	margin:0cm;
	margin-bottom:.0001pt;
	text-align:justify;
	text-justify:inter-ideograph;
	font-size:10.5pt;
	font-family:宋体;}
p.af, li.af, div.af
	{mso-style-name:习题标题;
	margin-top:6.0pt;
	margin-right:0cm;
	margin-bottom:0cm;
	margin-left:0cm;
	margin-bottom:.0001pt;
	text-align:justify;
	text-justify:inter-ideograph;
	page-break-after:avoid;
	font-size:14.0pt;
	font-family:黑体;}
p.1c, li.1c, div.1c
	{mso-style-name:部分编号1;
	margin:0cm;
	margin-bottom:.0001pt;
	text-align:justify;
	text-justify:inter-ideograph;
	font-size:16.0pt;
	font-family:宋体;}
p.af0, li.af0, div.af0
	{mso-style-name:表标题;
	margin:0cm;
	margin-bottom:.0001pt;
	text-align:center;
	font-size:10.5pt;
	font-family:"Arial","sans-serif";}
p.af1, li.af1, div.af1
	{mso-style-name:"样式 题注 + 居中";
	margin:0cm;
	margin-bottom:.0001pt;
	text-align:center;
	font-size:10.5pt;
	font-family:宋体;}
p.ListTitle, li.ListTitle, div.ListTitle
	{mso-style-name:ListTitle;
	margin:0cm;
	margin-bottom:.0001pt;
	text-align:justify;
	text-justify:inter-ideograph;
	font-size:10.5pt;
	font-family:"Arial","sans-serif";}
p.FigureTitle, li.FigureTitle, div.FigureTitle
	{mso-style-name:FigureTitle;
	margin:0cm;
	margin-bottom:.0001pt;
	text-align:center;
	font-size:10.5pt;
	font-family:"Arial","sans-serif";}
p.TableTitle, li.TableTitle, div.TableTitle
	{mso-style-name:TableTitle;
	margin:0cm;
	margin-bottom:.0001pt;
	text-align:center;
	font-size:10.5pt;
	font-family:"Arial","sans-serif";}
p.ProgramTitle, li.ProgramTitle, div.ProgramTitle
	{mso-style-name:ProgramTitle;
	margin:0cm;
	margin-bottom:.0001pt;
	text-align:center;
	font-size:10.5pt;
	font-family:"Arial","sans-serif";}
p.RightText, li.RightText, div.RightText
	{mso-style-name:RightText;
	margin-top:0cm;
	margin-right:21.0pt;
	margin-bottom:0cm;
	margin-left:42.0pt;
	margin-bottom:.0001pt;
	text-align:justify;
	text-justify:inter-ideograph;
	border:none;
	padding:0cm;
	font-size:9.0pt;
	font-family:宋体;}
p.af2, li.af2, div.af2
	{mso-style-name:表中文字小五;
	margin:0cm;
	margin-bottom:.0001pt;
	text-align:justify;
	text-justify:inter-ideograph;
	font-size:9.0pt;
	font-family:宋体;}
p.af3, li.af3, div.af3
	{mso-style-name:关键词;
	mso-style-link:"关键词 Char";
	margin:0cm;
	margin-bottom:.0001pt;
	text-align:justify;
	text-justify:inter-ideograph;
	font-size:10.5pt;
	font-family:宋体;}
span.Char3
	{mso-style-name:"关键词 Char";
	mso-style-link:关键词;
	font-family:宋体;}
p.af4, li.af4, div.af4
	{mso-style-name:文件名;
	mso-style-link:"文件名 Char";
	margin:0cm;
	margin-bottom:.0001pt;
	text-align:justify;
	text-justify:inter-ideograph;
	font-size:10.5pt;
	font-family:宋体;}
span.Char4
	{mso-style-name:"文件名 Char";
	mso-style-link:文件名;
	font-family:宋体;}
p.af5, li.af5, div.af5
	{mso-style-name:选项;
	mso-style-link:"选项 Char";
	margin:0cm;
	margin-bottom:.0001pt;
	text-align:justify;
	text-justify:inter-ideograph;
	font-size:10.5pt;
	font-family:宋体;}
span.Char5
	{mso-style-name:"选项 Char";
	mso-style-link:选项;
	font-family:宋体;}
p.af6, li.af6, div.af6
	{mso-style-name:命令行;
	mso-style-link:"命令行 Char";
	margin:0cm;
	margin-bottom:.0001pt;
	text-align:justify;
	text-justify:inter-ideograph;
	font-size:10.5pt;
	font-family:宋体;}
span.Char6
	{mso-style-name:"命令行 Char";
	mso-style-link:命令行;
	font-family:宋体;}
p.af7, li.af7, div.af7
	{mso-style-name:函数名;
	mso-style-link:"函数名 Char";
	margin:0cm;
	margin-bottom:.0001pt;
	text-align:justify;
	text-justify:inter-ideograph;
	font-size:10.5pt;
	font-family:宋体;}
span.Char7
	{mso-style-name:"函数名 Char";
	mso-style-link:函数名;
	font-family:宋体;}
p.af8, li.af8, div.af8
	{mso-style-name:寄存器名;
	mso-style-link:"寄存器名 Char";
	margin:0cm;
	margin-bottom:.0001pt;
	text-align:justify;
	text-justify:inter-ideograph;
	font-size:10.5pt;
	font-family:宋体;}
span.Char8
	{mso-style-name:"寄存器名 Char";
	mso-style-link:寄存器名;
	font-family:"Times New Roman","serif";}
p.af9, li.af9, div.af9
	{mso-style-name:变量名;
	mso-style-link:"变量名 Char";
	margin:0cm;
	margin-bottom:.0001pt;
	text-align:justify;
	text-justify:inter-ideograph;
	font-size:10.5pt;
	font-family:宋体;}
span.Char9
	{mso-style-name:"变量名 Char";
	mso-style-link:变量名;
	font-family:宋体;}
p.58, li.58, div.58
	{mso-style-name:图中文字小5号左;
	margin:0cm;
	margin-bottom:.0001pt;
	font-size:9.0pt;
	font-family:宋体;}
p.59, li.59, div.59
	{mso-style-name:图中文字小5号靠左;
	margin:0cm;
	margin-bottom:.0001pt;
	layout-grid-mode:char;
	font-size:9.0pt;
	font-family:宋体;}
p.926, li.926, div.926
	{mso-style-name:"样式 代码程序 + 左侧\:  9\.26 厘米";
	margin:0cm;
	margin-bottom:.0001pt;
	layout-grid-mode:char;
	font-size:10.0pt;
	font-family:宋体;}
span.5Char4
	{mso-style-name:"标题 5 Char";
	mso-style-link:"标题 5";
	font-weight:bold;}
span.6Char0
	{mso-style-name:"标题 6 Char";
	mso-style-link:"标题 6";
	font-family:"Arial","sans-serif";
	font-weight:bold;}
span.7Char
	{mso-style-name:"标题 7 Char";
	mso-style-link:"标题 7";
	font-weight:bold;}
span.8Char
	{mso-style-name:"标题 8 Char";
	mso-style-link:"标题 8";
	font-family:"Arial","sans-serif";}
span.9Char
	{mso-style-name:"标题 9 Char";
	mso-style-link:"标题 9";
	font-family:"Arial","sans-serif";}
span.Chara
	{mso-style-name:"脚注文本 Char";
	mso-style-link:脚注文本;
	font-family:宋体;}
span.Charb
	{mso-style-name:"批注文字 Char";
	mso-style-link:批注文字;
	font-family:宋体;}
span.Charc
	{mso-style-name:"页眉 Char";
	mso-style-link:页眉;
	font-family:宋体;}
span.Chard
	{mso-style-name:"页脚 Char";
	mso-style-link:页脚;
	font-family:宋体;}
span.Chare
	{mso-style-name:"日期 Char";
	mso-style-link:日期;
	font-family:宋体;}
span.HTMLChar
	{mso-style-name:"HTML 预设格式 Char\,HTML 预先格式化 Char\,HTML 预先格式化1 Char\,HTML 预先格式化2 Char\,HTML 预先格式化3 Char";
	mso-style-link:"HTML 预设格式\,HTML 预先格式化\,HTML 预先格式化1\,HTML 预先格式化2\,HTML 预先格式化3";
	font-family:宋体;}
span.Charf
	{mso-style-name:"批注主题 Char";
	mso-style-link:批注主题;
	font-family:宋体;
	font-weight:bold;}
span.Charf0
	{mso-style-name:"批注框文本 Char";
	mso-style-link:批注框文本;
	font-family:宋体;}
span.3CharChar1
	{mso-style-name:"图中文字3 Char Char1";
	font-family:宋体;}
span.3CharChar3
	{mso-style-name:"图中文字3 Char Char3";
	font-family:宋体;}
.MsoChpDefault
	{font-size:10.0pt;}
 /* Page Definitions */
 @page WordSection1
	{size:595.3pt 841.9pt;
	margin:72.0pt 54.0pt 72.0pt 54.0pt;
	layout-grid:15.6pt;}
div.WordSection1
	{page:WordSection1;}
 /* List Definitions */
 ol
	{margin-bottom:0cm;}
ul
	{margin-bottom:0cm;}
-->
</style>

</head>

<body lang=ZH-CN link=blue vlink=purple style='text-justify-trim:punctuation'>

<div class=WordSection1 style='layout-grid:15.6pt'>

<p class=ab><span style='font-family:黑体'>程序</span><span lang=EN-US>12-18 linux/fs/select.c</span></p>

<div class=a align=center style='text-align:center'><span lang=EN-US>

<hr size=4 width="100%" align=center>

</span></div>

<p class=a><span lang=EN-US>&nbsp; <u><span style='color:blue'>1</span></u> <b><i>/*</i></b></span></p>

<p class=a><span lang=EN-US>&nbsp; <u><span style='color:blue'>2</span></u> <b><i>&nbsp;*
This file contains the procedures for the handling of select</i></b></span></p>

<p class=a><span lang=EN-US>&nbsp; <u><span style='color:blue'>3</span></u> <b><i>&nbsp;*</i></b></span></p>

<p class=a><span lang=EN-US>&nbsp; <u><span style='color:blue'>4</span></u> <b><i>&nbsp;*
Created for Linux based loosely upon Mathius Lattner's minix</i></b></span></p>

<p class=a><span lang=EN-US>&nbsp; <u><span style='color:blue'>5</span></u> <b><i>&nbsp;*
patches by Peter MacDonald. Heavily edited by Linus.</i></b></span></p>

<p class=a><span lang=EN-US>&nbsp; <u><span style='color:blue'>6</span></u> <b><i>&nbsp;*/</i></b></span></p>

<p class=a><span lang=EN-US>&nbsp;&nbsp;&nbsp; /*</span></p>

<p class=a><span lang=EN-US>&nbsp;&nbsp;&nbsp;&nbsp; * </span>本文件含有处理<span
lang=EN-US>select()</span>系统调用的过程。</p>

<p class=a><span lang=EN-US>&nbsp;&nbsp;&nbsp;&nbsp; * </span></p>

<p class=a><span lang=EN-US>&nbsp;&nbsp;&nbsp;&nbsp; * </span>这是<span
lang=EN-US>Peter MacDonald</span>基于<span lang=EN-US>Mathius Lattner</span>提供给<span
lang=EN-US>MINIX</span>系统的补丁</p>

<p class=a><span lang=EN-US>&nbsp;&nbsp;&nbsp;&nbsp; * </span>程序修改而成。</p>

<p class=a><span lang=EN-US>&nbsp;&nbsp;&nbsp;&nbsp; */</span></p>

<p class=a><span lang=EN-US>&nbsp; <u><span style='color:blue'>7</span></u> </span></p>

<p class=a><span lang=EN-US>&nbsp; <u><span style='color:blue'>8</span></u>
#include &lt;linux/fs.h&gt;</span></p>

<p class=a><span lang=EN-US>&nbsp; <u><span style='color:blue'>9</span></u>
#include &lt;linux/kernel.h&gt;</span></p>

<p class=a><span lang=EN-US>&nbsp;<u><span style='color:blue'>10</span></u>
#include &lt;linux/tty.h&gt;</span></p>

<p class=a><span lang=EN-US>&nbsp;<u><span style='color:blue'>11</span></u>
#include &lt;linux/sched.h&gt;</span></p>

<p class=a><span lang=EN-US>&nbsp;<u><span style='color:blue'>12</span></u> </span></p>

<p class=a><span lang=EN-US>&nbsp;<u><span style='color:blue'>13</span></u>
#include &lt;asm/segment.h&gt;</span></p>

<p class=a><span lang=EN-US>&nbsp;<u><span style='color:blue'>14</span></u>
#include &lt;asm/system.h&gt;</span></p>

<p class=a><span lang=EN-US>&nbsp;<u><span style='color:blue'>15</span></u> </span></p>

<p class=a><span lang=EN-US>&nbsp;<u><span style='color:blue'>16</span></u>
#include &lt;sys/stat.h&gt;</span></p>

<p class=a><span lang=EN-US>&nbsp;<u><span style='color:blue'>17</span></u>
#include &lt;sys/types.h&gt;</span></p>

<p class=a><span lang=EN-US>&nbsp;<u><span style='color:blue'>18</span></u>
#include &lt;string.h&gt;</span></p>

<p class=a><span lang=EN-US>&nbsp;<u><span style='color:blue'>19</span></u>
#include &lt;const.h&gt;</span></p>

<p class=a><span lang=EN-US>&nbsp;<u><span style='color:blue'>20</span></u>
#include &lt;errno.h&gt;</span></p>

<p class=a><span lang=EN-US>&nbsp;<u><span style='color:blue'>21</span></u>
#include &lt;sys/time.h&gt;</span></p>

<p class=a><span lang=EN-US>&nbsp;<u><span style='color:blue'>22</span></u>
#include &lt;signal.h&gt;</span></p>

<p class=a><span lang=EN-US>&nbsp;<u><span style='color:blue'>23</span></u> </span></p>

<p class=a><span lang=EN-US>&nbsp;<u><span style='color:blue'>24</span></u> <b><i>/*</i></b></span></p>

<p class=a><span lang=EN-US>&nbsp;<u><span style='color:blue'>25</span></u> <b><i>&nbsp;*
Ok, Peter made a complicated, but straightforward multiple_wait() function.</i></b></span></p>

<p class=a><span lang=EN-US>&nbsp;<u><span style='color:blue'>26</span></u> <b><i>&nbsp;*
I have rewritten this, taking some shortcuts: This code may not be easy to</i></b></span></p>

<p class=a><span lang=EN-US>&nbsp;<u><span style='color:blue'>27</span></u> <b><i>&nbsp;*
follow, but it should be free of race-conditions, and it's practical. If you</i></b></span></p>

<p class=a><span lang=EN-US>&nbsp;<u><span style='color:blue'>28</span></u> <b><i>&nbsp;*
understand what I'm doing here, then you understand how the linux sleep/wakeup</i></b></span></p>

<p class=a><span lang=EN-US>&nbsp;<u><span style='color:blue'>29</span></u> <b><i>&nbsp;*
mechanism works.</i></b></span></p>

<p class=a><span lang=EN-US>&nbsp;<u><span style='color:blue'>30</span></u> <b><i>&nbsp;*</i></b></span></p>

<p class=a><span lang=EN-US>&nbsp;<u><span style='color:blue'>31</span></u> <b><i>&nbsp;*
Two very simple procedures, add_wait() and free_wait() make all the work. We</i></b></span></p>

<p class=a><span lang=EN-US>&nbsp;<u><span style='color:blue'>32</span></u> <b><i>&nbsp;*
have to have interrupts disabled throughout the select, but that's not really</i></b></span></p>

<p class=a><span lang=EN-US>&nbsp;<u><span style='color:blue'>33</span></u> <b><i>&nbsp;*
such a loss: sleeping automatically frees interrupts when we aren't in this</i></b></span></p>

<p class=a><span lang=EN-US>&nbsp;<u><span style='color:blue'>34</span></u> <b><i>&nbsp;*
task.</i></b></span></p>

<p class=a><span lang=EN-US>&nbsp;<u><span style='color:blue'>35</span></u> <b><i>&nbsp;*/</i></b></span></p>

<p class=a><span lang=EN-US>&nbsp;&nbsp;&nbsp; /*</span></p>

<p class=a><span lang=EN-US>&nbsp;&nbsp;&nbsp;&nbsp; * OK</span>，<span
lang=EN-US>Peter</span>编制了复杂但很直观的多个<span lang=EN-US>_wait()</span>函数。我对这些函数进行了改写，以使之</p>

<p class=a><span lang=EN-US>&nbsp;&nbsp;&nbsp;&nbsp; * </span>更简洁：这些代码可能不容易看懂，但是其中应该不会存在竞争条件问题，并且很实际。</p>

<p class=a><span lang=EN-US>&nbsp;&nbsp;&nbsp;&nbsp; * </span>如果你能理解这里编制的代码，那么就说明你已经理解<span
lang=EN-US>Linux</span>中睡眠<span lang=EN-US>/</span>唤醒的工作机制。</p>

<p class=a><span lang=EN-US>&nbsp;&nbsp;&nbsp;&nbsp; *</span></p>

<p class=a><span lang=EN-US>&nbsp;&nbsp;&nbsp;&nbsp; * </span>两个很简单的过程，<span
lang=EN-US>add_wait()</span>和<span lang=EN-US>free_wait()</span>执行了主要操作。在整个<span
lang=EN-US>select</span>处理</p>

<p class=a><span lang=EN-US>&nbsp;&nbsp;&nbsp;&nbsp; * </span>过程中我们不得不禁止中断。但是这样做并不会带来太多的损失：因为当我们不在执行</p>

<p class=a><span lang=EN-US>&nbsp;&nbsp;&nbsp;&nbsp; * </span>本任务时睡眠状态会自动地释放中断（即其他任务会使用自己<span
lang=EN-US>EFLAGS</span>中的中断标志）。</p>

<p class=a><span lang=EN-US>&nbsp;&nbsp;&nbsp;&nbsp; */</span></p>

<p class=a><span lang=EN-US>&nbsp;<u><span style='color:blue'>36</span></u> </span></p>

<p class=a><span lang=EN-US>&nbsp;<u><span style='color:blue'>37</span></u>
typedef struct {</span></p>

<p class=a><span lang=EN-US>&nbsp;<u><span style='color:blue'>38</span></u>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
struct <u><span style='color:blue'>task_struct</span></u> * old_task;</span></p>

<p class=a><span lang=EN-US>&nbsp;<u><span style='color:blue'>39</span></u>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
struct <u><span style='color:blue'>task_struct</span></u> ** wait_address;</span></p>

<p class=a><span lang=EN-US>&nbsp;<u><span style='color:blue'>40</span></u> } <u><span
style='color:blue'>wait_entry</span></u>;</span></p>

<p class=a><span lang=EN-US>&nbsp;<u><span style='color:blue'>41</span></u> </span></p>

<p class=a><span lang=EN-US>&nbsp;<u><span style='color:blue'>42</span></u>
typedef struct {</span></p>

<p class=a><span lang=EN-US>&nbsp;<u><span style='color:blue'>43</span></u>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
int nr;</span></p>

<p class=a><span lang=EN-US>&nbsp;<u><span style='color:blue'>44</span></u>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
<u><span style='color:blue'>wait_entry</span></u> entry[<u><span
style='color:blue'>NR_OPEN</span></u>*3];</span></p>

<p class=a><span lang=EN-US>&nbsp;<u><span style='color:blue'>45</span></u> } <u><span
style='color:blue'>select_table</span></u>;</span></p>

<p class=a><span lang=EN-US>&nbsp;<u><span style='color:blue'>46</span></u> </span></p>

<p class=a><span lang=EN-US>&nbsp;&nbsp;&nbsp; // </span>把未准备好描述符的等待队列指针加入等待表<span
lang=EN-US>wait_table</span>中。参数<span lang=EN-US>*wait_address</span>是与描述</p>

<p class=a><span lang=EN-US>&nbsp;&nbsp;&nbsp; // </span>符相关的等待队列头指针。例如<span
lang=EN-US>tty</span>读缓冲队列<span lang=EN-US>secondary</span>的等待队列头指针是<span
lang=EN-US>proc_list</span>。</p>

<p class=a><span lang=EN-US>&nbsp;&nbsp;&nbsp; // </span>参数 <span lang=EN-US>p</span>是<span
lang=EN-US>do_select()</span>中定义的等待表结构指针。</p>

<p class=a><span lang=EN-US>&nbsp;<u><span style='color:blue'>47</span></u>
static void <u><span style='color:blue'>add_wait</span></u>(struct <u><span
style='color:blue'>task_struct</span></u> ** wait_address, <u><span
style='color:blue'>select_table</span></u> * p)</span></p>

<p class=a><span lang=EN-US>&nbsp;<u><span style='color:blue'>48</span></u> {</span></p>

<p class=a><span lang=EN-US>&nbsp;<u><span style='color:blue'>49</span></u>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
int i;</span></p>

<p class=a><span lang=EN-US>&nbsp;<u><span style='color:blue'>50</span></u> </span></p>

<p class=a><span lang=EN-US>&nbsp;&nbsp;&nbsp; // </span>首先判断描述符是否有对应的等待队列，若无则返回。然后在等待表中搜索参数指定的等待</p>

<p class=a><span lang=EN-US>&nbsp;&nbsp;&nbsp; // </span>队列指针是否已经在等待表中设置过，若设置过也立刻返回。这个判断主要是针对管道文件</p>

<p class=a><span lang=EN-US>&nbsp;&nbsp;&nbsp; // </span>描述符。例如若一个管道在等待可以进行读操作，那么其必定可以立刻进行写操作。</p>

<p class=a><span lang=EN-US>&nbsp;<u><span style='color:blue'>51</span></u>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
if (!wait_address)</span></p>

<p class=a><span lang=EN-US>&nbsp;<u><span style='color:blue'>52</span></u>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
return;</span></p>

<p class=a><span lang=EN-US>&nbsp;<u><span style='color:blue'>53</span></u>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
for (i = 0 ; i &lt; p-&gt;nr ; i++)</span></p>

<p class=a><span lang=EN-US>&nbsp;<u><span style='color:blue'>54</span></u>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
if (p-&gt;entry[i].wait_address == wait_address)</span></p>

<p class=a><span lang=EN-US>&nbsp;<u><span style='color:blue'>55</span></u>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
return;</span></p>

<p class=a><span lang=EN-US>&nbsp;&nbsp;&nbsp; // </span>然后我们把描述符对应等待队列的头指针保存在等待表<span
lang=EN-US>wait_table</span>中，同时让等待表项的</p>

<p class=a><span lang=EN-US>&nbsp;&nbsp;&nbsp; // old_task</span>字段指向等待队列头指针指向的任务（若无则为<span
lang=EN-US>NULL</span>），在让等待队列头指针指</p>

<p class=a><span lang=EN-US>&nbsp;&nbsp;&nbsp; // </span>向当前任务。最后把等待表有效项计数值<span
lang=EN-US>nr</span>增<span lang=EN-US>1</span>（其在第<span lang=EN-US>179</span>行被初始化为<span
lang=EN-US>0</span>）。</p>

<p class=a><span lang=EN-US>&nbsp;<u><span style='color:blue'>56</span></u>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
p-&gt;entry[p-&gt;nr].wait_address = wait_address;</span></p>

<p class=a><span lang=EN-US>&nbsp;<u><span style='color:blue'>57</span></u>&nbsp;&nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp;&nbsp;p-&gt;entry[p-&gt;nr].old_task = * wait_address;</span></p>

<p class=a><span lang=EN-US>&nbsp;<u><span style='color:blue'>58</span></u>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
*wait_address = <u><span style='color:blue'>current</span></u>;</span></p>

<p class=a><span lang=EN-US>&nbsp;<u><span style='color:blue'>59</span></u>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
p-&gt;nr++;</span></p>

<p class=a><span lang=EN-US>&nbsp;<u><span style='color:blue'>60</span></u> }</span></p>

<p class=a><span lang=EN-US>&nbsp;<u><span style='color:blue'>61</span></u> </span></p>

<p class=a><span lang=EN-US>&nbsp;&nbsp;&nbsp; // </span>清空等待表。参数是等待表结构指针。本函数在<span
lang=EN-US>do_select()</span>函数中睡眠后被唤醒返回时被调用</p>

<p class=a><span lang=EN-US>&nbsp;&nbsp;&nbsp; // </span>（第<span lang=EN-US>204</span>、<span
lang=EN-US>207</span>行），用于唤醒等待表中处于各个等待队列上的其他任务。它与<span lang=EN-US>kernel/sched.c</span></p>

<p class=a><span lang=EN-US>&nbsp;&nbsp;&nbsp; // </span>中<span lang=EN-US>sleep_on()</span>函数的后半部分代码几乎完全相同，请参考对<span
lang=EN-US>sleep_on()</span>函数的说明。</p>

<p class=a><span lang=EN-US>&nbsp;<u><span style='color:blue'>62</span></u>
static void <u><span style='color:blue'>free_wait</span></u>(<u><span
style='color:blue'>select_table</span></u> * p)</span></p>

<p class=a><span lang=EN-US>&nbsp;<u><span style='color:blue'>63</span></u> {</span></p>

<p class=a><span lang=EN-US>&nbsp;<u><span style='color:blue'>64</span></u>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
int i;</span></p>

<p class=a><span lang=EN-US>&nbsp;<u><span style='color:blue'>65</span></u>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
struct <u><span style='color:blue'>task_struct</span></u> ** tpp;</span></p>

<p class=a><span lang=EN-US>&nbsp;<u><span style='color:blue'>66</span></u> </span></p>

<p class=a><span lang=EN-US>&nbsp;&nbsp;&nbsp; // </span>如果等待表中各项（供<span
lang=EN-US>nr </span>个有效项）记录的等待队列头指针表明还有其他后来添加进的等待</p>

<p class=a><span lang=EN-US>&nbsp;&nbsp;&nbsp; // </span>任务（例如其他进程调用 <span
lang=EN-US>sleep_on() </span>函数而睡眠在该等待队列上），则此时等待队列头指针</p>

<p class=a><span lang=EN-US>&nbsp;&nbsp;&nbsp; // </span>指向的不是当前进程，那么我们就需要先唤醒这些任务。操作方法是将等待队列头所指任务先</p>

<p class=a><span lang=EN-US>&nbsp;&nbsp;&nbsp; // </span>置为就绪状态（<span
lang=EN-US>state = 0</span>），并把自己设置为不可中断等待状态，即自己要等待这些后续进队</p>

<p class=a><span lang=EN-US>&nbsp;&nbsp;&nbsp; // </span>列的任务被唤醒而执行时来唤醒本任务。然后重新执行调度程序。</p>

<p class=a><span lang=EN-US>&nbsp;<u><span style='color:blue'>67</span></u>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
for (i = 0; i &lt; p-&gt;nr ; i++) {</span></p>

<p class=a><span lang=EN-US>&nbsp;<u><span style='color:blue'>68</span></u>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
tpp = p-&gt;entry[i].wait_address;</span></p>

<p class=a><span lang=EN-US>&nbsp;<u><span style='color:blue'>69</span></u>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
while (*tpp &amp;&amp; *tpp != <u><span style='color:blue'>current</span></u>)
{</span></p>

<p class=a><span lang=EN-US>&nbsp;<u><span style='color:blue'>70</span></u>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
(*tpp)-&gt;<u><span style='color:blue'>state</span></u> = 0;</span></p>

<p class=a><span lang=EN-US>&nbsp;<u><span style='color:blue'>71</span></u>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
<u><span style='color:blue'>current</span></u>-&gt;<u><span style='color:blue'>state</span></u>
= <u><span style='color:blue'>TASK_UNINTERRUPTIBLE</span></u>;</span></p>

<p class=a><span lang=EN-US>&nbsp;<u><span style='color:blue'>72</span></u>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
<u><span style='color:blue'>schedule</span></u>();</span></p>

<p class=a><span lang=EN-US>&nbsp;<u><span style='color:blue'>73</span></u>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
}</span></p>

<p class=a><span lang=EN-US>&nbsp;&nbsp;&nbsp; // </span>执行到这里，说明等待表当前处理项中的等待队列头指针字段<span
lang=EN-US>wait_address</span>指向当前任务，</p>

<p class=a><span lang=EN-US>&nbsp;&nbsp;&nbsp; // </span>若它为空，则表明调度有问题，于是显示警告信息。然后我们让等待队列头指针指向在我们</p>

<p class=a><span lang=EN-US>&nbsp;&nbsp;&nbsp; // </span>前面进入队列的任务（第<span
lang=EN-US>76</span>行）。若此时该头指针确实指向一个任务而不是<span lang=EN-US>NULL</span>，则说明</p>

<p class=a><span lang=EN-US>&nbsp;&nbsp;&nbsp; // </span>队列中还有任务（<span
lang=EN-US>*tpp</span>不为空），于是将该任务设置成就绪状态，唤醒之。最后把等待表的</p>

<p class=a><span lang=EN-US>&nbsp;&nbsp;&nbsp; // </span>有效表项计数字段<span
lang=EN-US>nr</span>清零。</p>

<p class=a><span lang=EN-US>&nbsp;<u><span style='color:blue'>74</span></u>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
if (!*tpp)</span></p>

<p class=a><span lang=EN-US>&nbsp;<u><span style='color:blue'>75</span></u>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
<u><span style='color:blue'>printk</span></u>(<i>&quot;free_wait: NULL&quot;</i>);</span></p>

<p class=a><span lang=EN-US>&nbsp;<u><span style='color:blue'>76</span></u>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
if (*tpp = p-&gt;entry[i].old_task)</span></p>

<p class=a><span lang=EN-US>&nbsp;<u><span style='color:blue'>77</span></u>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
(**tpp).<u><span style='color:blue'>state</span></u> = 0;</span></p>

<p class=a><span lang=EN-US>&nbsp;<u><span style='color:blue'>78</span></u>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
}</span></p>

<p class=a><span lang=EN-US>&nbsp;<u><span style='color:blue'>79</span></u>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
p-&gt;nr = 0;</span></p>

<p class=a><span lang=EN-US>&nbsp;<u><span style='color:blue'>80</span></u> }</span></p>

<p class=a><span lang=EN-US>&nbsp;<u><span style='color:blue'>81</span></u> </span></p>

<p class=a><span lang=EN-US>&nbsp;&nbsp;&nbsp; // </span>根据文件<span lang=EN-US>i</span>节点判断文件是否是字符终端设备文件。若是则返回其<span
lang=EN-US>tty</span>结构指针，否则返回<span lang=EN-US>NULL</span>。</p>

<p class=a><span lang=EN-US>&nbsp;<u><span style='color:blue'>82</span></u>
static struct <u><span style='color:blue'>tty_struct</span></u> * <u><span
style='color:blue'>get_tty</span></u>(struct <u><span style='color:blue'>m_inode</span></u>
* inode)</span></p>

<p class=a><span lang=EN-US>&nbsp;<u><span style='color:blue'>83</span></u> {</span></p>

<p class=a><span lang=EN-US>&nbsp;<u><span style='color:blue'>84</span></u>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
int major, minor;</span></p>

<p class=a><span lang=EN-US>&nbsp;<u><span style='color:blue'>85</span></u> </span></p>

<p class=a><span lang=EN-US>&nbsp;&nbsp;&nbsp; // </span>如果不是字符设备文件则返回<span
lang=EN-US>NULL</span>。如果主设备号不是<span lang=EN-US>5</span>（控制终端）或<span
lang=EN-US>4</span>，则返回<span lang=EN-US>NULL</span>。</p>

<p class=a><span lang=EN-US>&nbsp;<u><span style='color:blue'>86</span></u>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
if (!<u><span style='color:blue'>S_ISCHR</span></u>(inode-&gt;i_mode))</span></p>

<p class=a><span lang=EN-US>&nbsp;<u><span style='color:blue'>87</span></u>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
return <u><span style='color:blue'>NULL</span></u>;</span></p>

<p class=a><span lang=EN-US>&nbsp;<u><span style='color:blue'>88</span></u>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
if ((major = <u><span style='color:blue'>MAJOR</span></u>(inode-&gt;i_zone[0]))
!= 5 &amp;&amp; major != 4)</span></p>

<p class=a><span lang=EN-US>&nbsp;<u><span style='color:blue'>89</span></u>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
return <u><span style='color:blue'>NULL</span></u>;</span></p>

<p class=a><span lang=EN-US>&nbsp;&nbsp;&nbsp; // </span>如果主设备号是<span
lang=EN-US>5</span>，那么其终端设备号等于进程的<span lang=EN-US>tty</span>字段值，否则就等于字符设备文件次设备号。</p>

<p class=a><span lang=EN-US>&nbsp;&nbsp;&nbsp; // </span>如果终端设备号小于<span
lang=EN-US>0</span>，表示进程没有控制终端或没有使用终端，于是返回<span lang=EN-US>NULL</span>。否则返回对应的</p>

<p class=a><span lang=EN-US>&nbsp;&nbsp;&nbsp; // tty</span>结构指针。</p>

<p class=a><span lang=EN-US>&nbsp;<u><span style='color:blue'>90</span></u>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
if (major == 5)</span></p>

<p class=a><span lang=EN-US>&nbsp;<u><span style='color:blue'>91</span></u>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
minor = <u><span style='color:blue'>current</span></u>-&gt;tty;</span></p>

<p class=a><span lang=EN-US>&nbsp;<u><span style='color:blue'>92</span></u>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
else</span></p>

<p class=a><span lang=EN-US>&nbsp;<u><span style='color:blue'>93</span></u>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp;&nbsp;minor = <u><span style='color:blue'>MINOR</span></u>(inode-&gt;i_zone[0]);</span></p>

<p class=a><span lang=EN-US>&nbsp;<u><span style='color:blue'>94</span></u>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
if (minor &lt; 0)</span></p>

<p class=a><span lang=EN-US>&nbsp;<u><span style='color:blue'>95</span></u>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
return <u><span style='color:blue'>NULL</span></u>;</span></p>

<p class=a><span lang=EN-US>&nbsp;<u><span style='color:blue'>96</span></u>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
return <u><span style='color:blue'>TTY_TABLE</span></u>(minor);</span></p>

<p class=a><span lang=EN-US>&nbsp;<u><span style='color:blue'>97</span></u> }</span></p>

<p class=a><span lang=EN-US>&nbsp;<u><span style='color:blue'>98</span></u> </span></p>

<p class=a><span lang=EN-US>&nbsp;<u><span style='color:blue'>99</span></u> <b><i>/*</i></b></span></p>

<p class=a><u><span lang=EN-US style='color:blue'>100</span></u><span
lang=EN-US> <b><i>&nbsp;* The check_XX functions check out a file. We know it's
either</i></b></span></p>

<p class=a><u><span lang=EN-US style='color:blue'>101</span></u><span
lang=EN-US> <b><i>&nbsp;* a pipe, a character device or a fifo (fifo's not
implemented)</i></b></span></p>

<p class=a><u><span lang=EN-US style='color:blue'>102</span></u><span
lang=EN-US> <b><i>&nbsp;*/</i></b></span></p>

<p class=a><span lang=EN-US>&nbsp;&nbsp;&nbsp; /*</span></p>

<p class=a><span lang=EN-US>&nbsp;&nbsp;&nbsp;&nbsp; * check_XX</span>函数用于检查一个文件。我们知道该文件要么是管道文件、</p>

<p class=a><span lang=EN-US>&nbsp;&nbsp;&nbsp;&nbsp; * </span>要么是字符设备文件，或者要么是一个<span
lang=EN-US>FIFO</span>（<span lang=EN-US>FIFO</span>还未实现）。</p>

<p class=a><span lang=EN-US>&nbsp;&nbsp;&nbsp;&nbsp; */</span></p>

<p class=a><span lang=EN-US>&nbsp;&nbsp;&nbsp; // </span>检查读文件操作是否准备好，即终端读缓冲队列<span
lang=EN-US>secondary</span>是否有字符可读，或者管道文件是否</p>

<p class=a><span lang=EN-US>&nbsp;&nbsp;&nbsp; // </span>不空。参数<span lang=EN-US>wait</span>是等待表指针；<span
lang=EN-US>inode</span>是文件<span lang=EN-US>i</span>节点指针。若描述符可进行读操作则返回<span
lang=EN-US>1</span>，否</p>

<p class=a><span lang=EN-US>&nbsp;&nbsp;&nbsp; // </span>则返回<span lang=EN-US>0</span>。</p>

<p class=a><u><span lang=EN-US style='color:blue'>103</span></u><span
lang=EN-US> static int <u><span style='color:blue'>check_in</span></u>(<u><span
style='color:blue'>select_table</span></u> * <u><span style='color:blue'>wait</span></u>,
struct <u><span style='color:blue'>m_inode</span></u> * inode)</span></p>

<p class=a><u><span lang=EN-US style='color:blue'>104</span></u><span
lang=EN-US> {</span></p>

<p class=a><u><span lang=EN-US style='color:blue'>105</span></u><span
lang=EN-US>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; struct <u><span
style='color:blue'>tty_struct</span></u> * tty;</span></p>

<p class=a><u><span lang=EN-US style='color:blue'>106</span></u><span
lang=EN-US> </span></p>

<p class=a><span lang=EN-US>&nbsp;&nbsp;&nbsp; // </span>首先根据文件<span
lang=EN-US>i</span>节点调用<span lang=EN-US>get_tty()</span>检测文件是否是一个<span
lang=EN-US>tty</span>终端（字符）设备文件，如果是则</p>

<p class=a><span lang=EN-US>&nbsp;&nbsp;&nbsp; // </span>检查该终端读缓冲队列<span
lang=EN-US>secondary</span>中是否有字符可供读取，若有则返回<span lang=EN-US>1</span>，若此时<span
lang=EN-US>secondary</span>为</p>

<p class=a><span lang=EN-US>&nbsp;&nbsp;&nbsp; // </span>空则把当前任务添加到<span
lang=EN-US>secondary</span>的等待队列<span lang=EN-US>proc_list</span>上并返回<span
lang=EN-US>0</span>。如果是管道文件，则判断</p>

<p class=a><span lang=EN-US>&nbsp;&nbsp;&nbsp; // </span>目前管道中是否有字符可读，若有则返回<span
lang=EN-US>1</span>，若没有（管道空）则把当前任务添加到管道<span lang=EN-US>i</span>节点</p>

<p class=a><span lang=EN-US>&nbsp;&nbsp;&nbsp; // </span>的等待队列上并返回<span
lang=EN-US>0</span>。注意，<span lang=EN-US>PIPE_EMPTY()</span>宏使用管道当前头尾指针位置来判断管道是否空。</p>

<p class=a><span lang=EN-US>&nbsp;&nbsp;&nbsp; // </span>管道<span lang=EN-US>i</span>节点的<span
lang=EN-US>i_zone[0]</span>和<span lang=EN-US>i_zone[1]</span>字段分别存放着管道当前的头尾指针。</p>

<p class=a><u><span lang=EN-US style='color:blue'>107</span></u><span
lang=EN-US>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (tty = <u><span
style='color:blue'>get_tty</span></u>(inode))</span></p>

<p class=a><u><span lang=EN-US style='color:blue'>108</span></u><span
lang=EN-US>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
if (!<u><span style='color:blue'>EMPTY</span></u>(tty-&gt;secondary))</span></p>

<p class=a><u><span lang=EN-US style='color:blue'>109</span></u><span
lang=EN-US>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
return 1;</span></p>

<p class=a><u><span lang=EN-US style='color:blue'>110</span></u><span
lang=EN-US>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
else</span></p>

<p class=a><u><span lang=EN-US style='color:blue'>111</span></u><span
lang=EN-US>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
<u><span style='color:blue'>add_wait</span></u>(&amp;tty-&gt;secondary-&gt;proc_list,
<u><span style='color:blue'>wait</span></u>);</span></p>

<p class=a><u><span lang=EN-US style='color:blue'>112</span></u><span
lang=EN-US>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; else if
(inode-&gt;i_pipe)</span></p>

<p class=a><u><span lang=EN-US style='color:blue'>113</span></u><span
lang=EN-US>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
if (!<u><span style='color:blue'>PIPE_EMPTY</span></u>(*inode))</span></p>

<p class=a><u><span lang=EN-US style='color:blue'>114</span></u><span
lang=EN-US>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
return 1;</span></p>

<p class=a><u><span lang=EN-US style='color:blue'>115</span></u><span
lang=EN-US>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
else</span></p>

<p class=a><u><span lang=EN-US style='color:blue'>116</span></u><span
lang=EN-US>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
<u><span style='color:blue'>add_wait</span></u>(&amp;inode-&gt;i_wait, <u><span
style='color:blue'>wait</span></u>);</span></p>

<p class=a><u><span lang=EN-US style='color:blue'>117</span></u><span
lang=EN-US>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return 0;</span></p>

<p class=a><u><span lang=EN-US style='color:blue'>118</span></u><span
lang=EN-US> }</span></p>

<p class=a><u><span lang=EN-US style='color:blue'>119</span></u><span
lang=EN-US> </span></p>

<p class=a><span lang=EN-US>&nbsp;&nbsp;&nbsp; // </span>检查文件写操作是否准备好，即终端写缓冲队列<span
lang=EN-US>write_q</span>中是否还有空闲位置可写，或者此时管</p>

<p class=a><span lang=EN-US>&nbsp;&nbsp;&nbsp; // </span>道文件是否不满。参数<span
lang=EN-US>wait</span>是等待表指针；<span lang=EN-US>inode</span>是文件<span lang=EN-US>i</span>节点指针。若描述符可进行写操作则</p>

<p class=a><span lang=EN-US>&nbsp;&nbsp;&nbsp; // </span>返回<span lang=EN-US>1</span>，否则返回<span
lang=EN-US>0</span>。</p>

<p class=a><u><span lang=EN-US style='color:blue'>120</span></u><span
lang=EN-US> static int <u><span style='color:blue'>check_out</span></u>(<u><span
style='color:blue'>select_table</span></u> * <u><span style='color:blue'>wait</span></u>,
struct <u><span style='color:blue'>m_inode</span></u> * inode)</span></p>

<p class=a><u><span lang=EN-US style='color:blue'>121</span></u><span
lang=EN-US> {</span></p>

<p class=a><u><span lang=EN-US style='color:blue'>122</span></u><span
lang=EN-US>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; struct <u><span
style='color:blue'>tty_struct</span></u> * tty;</span></p>

<p class=a><u><span lang=EN-US style='color:blue'>123</span></u><span
lang=EN-US> </span></p>

<p class=a><span lang=EN-US>&nbsp;&nbsp;&nbsp; // </span>首先根据文件<span
lang=EN-US>i</span>节点调用<span lang=EN-US>get_tty()</span>检测文件是否是一个<span
lang=EN-US>tty</span>终端（字符）设备文件，如果是则</p>

<p class=a><span lang=EN-US>&nbsp;&nbsp;&nbsp; // </span>检查该终端写缓冲队列<span
lang=EN-US>write_q</span>中是否有空间可写入，若有则返回<span lang=EN-US>1</span>，若没有空空间则把当前任</p>

<p class=a><span lang=EN-US>&nbsp;&nbsp;&nbsp; // </span>务添加到<span lang=EN-US>write_q</span>的等待队列<span
lang=EN-US>proc_list</span>上并返回<span lang=EN-US>0</span>。如果是管道文件则判断目前管道中是否有</p>

<p class=a><span lang=EN-US>&nbsp;&nbsp;&nbsp; // </span>空闲空间可写入字符，若有则返回<span
lang=EN-US>1</span>，若没有（管道满）则把当前任务添加到管道<span lang=EN-US>i</span>节点的等待</p>

<p class=a><span lang=EN-US>&nbsp;&nbsp;&nbsp; // </span>队列上并返回<span
lang=EN-US>0</span>。</p>

<p class=a><u><span lang=EN-US style='color:blue'>124</span></u><span
lang=EN-US>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (tty = <u><span
style='color:blue'>get_tty</span></u>(inode))</span></p>

<p class=a><u><span lang=EN-US style='color:blue'>125</span></u><span
lang=EN-US>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
if (!<u><span style='color:blue'>FULL</span></u>(tty-&gt;write_q))</span></p>

<p class=a><u><span lang=EN-US style='color:blue'>126</span></u><span
lang=EN-US>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
return 1;</span></p>

<p class=a><u><span lang=EN-US style='color:blue'>127</span></u><span
lang=EN-US>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
else</span></p>

<p class=a><u><span lang=EN-US style='color:blue'>128</span></u><span
lang=EN-US>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
<u><span style='color:blue'>add_wait</span></u>(&amp;tty-&gt;write_q-&gt;proc_list,
<u><span style='color:blue'>wait</span></u>);</span></p>

<p class=a><u><span lang=EN-US style='color:blue'>129</span></u><span
lang=EN-US>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; else if
(inode-&gt;i_pipe)</span></p>

<p class=a><u><span lang=EN-US style='color:blue'>130</span></u><span
lang=EN-US>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
if (!<u><span style='color:blue'>PIPE_FULL</span></u>(*inode))</span></p>

<p class=a><u><span lang=EN-US style='color:blue'>131</span></u><span
lang=EN-US>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
return 1;</span></p>

<p class=a><u><span lang=EN-US style='color:blue'>132</span></u><span
lang=EN-US>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
else</span></p>

<p class=a><u><span lang=EN-US style='color:blue'>133</span></u><span
lang=EN-US>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<u><span
style='color:blue'>add_wait</span></u>(&amp;inode-&gt;i_wait, <u><span
style='color:blue'>wait</span></u>);</span></p>

<p class=a><u><span lang=EN-US style='color:blue'>134</span></u><span
lang=EN-US>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return 0;</span></p>

<p class=a><u><span lang=EN-US style='color:blue'>135</span></u><span
lang=EN-US> }</span></p>

<p class=a><u><span lang=EN-US style='color:blue'>136</span></u><span
lang=EN-US> </span></p>

<p class=a><span lang=EN-US>&nbsp;&nbsp;&nbsp; // </span>检查文件是否处于异常状态。对于终端设备文件，目前内核总是返回<span
lang=EN-US>0</span>。对于管道文件，如果</p>

<p class=a><span lang=EN-US>&nbsp;&nbsp;&nbsp; // </span>此时两个管道描述符中有一个或都已被关闭，则返回<span
lang=EN-US>1</span>，否则就把当前任务添加到管道<span lang=EN-US>i</span>节点</p>

<p class=a><span lang=EN-US>&nbsp;&nbsp;&nbsp; // </span>的等待队列上并返回<span
lang=EN-US>0</span>。返回<span lang=EN-US>0</span>。参数<span lang=EN-US>wait</span>是等待表指针；<span
lang=EN-US>inode</span>是文件<span lang=EN-US>i</span>节点指针。若出现</p>

<p class=a><span lang=EN-US>&nbsp;&nbsp;&nbsp; // </span>异常条件则返回<span
lang=EN-US>1</span>，否则返回<span lang=EN-US>0</span>。</p>

<p class=a><u><span lang=EN-US style='color:blue'>137</span></u><span
lang=EN-US> static int <u><span style='color:blue'>check_ex</span></u>(<u><span
style='color:blue'>select_table</span></u> * <u><span style='color:blue'>wait</span></u>,
struct <u><span style='color:blue'>m_inode</span></u> * inode)</span></p>

<p class=a><u><span lang=EN-US style='color:blue'>138</span></u><span
lang=EN-US> {</span></p>

<p class=a><u><span lang=EN-US style='color:blue'>139</span></u><span
lang=EN-US>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; struct <u><span
style='color:blue'>tty_struct</span></u> * tty;</span></p>

<p class=a><u><span lang=EN-US style='color:blue'>140</span></u><span
lang=EN-US> </span></p>

<p class=a><u><span lang=EN-US style='color:blue'>141</span></u><span
lang=EN-US>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (tty = <u><span
style='color:blue'>get_tty</span></u>(inode))</span></p>

<p class=a><u><span lang=EN-US style='color:blue'>142</span></u><span
lang=EN-US>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
if (!<u><span style='color:blue'>FULL</span></u>(tty-&gt;write_q))</span></p>

<p class=a><u><span lang=EN-US style='color:blue'>143</span></u><span
lang=EN-US>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
return 0;</span></p>

<p class=a><u><span lang=EN-US style='color:blue'>144</span></u><span
lang=EN-US>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
else</span></p>

<p class=a><u><span lang=EN-US style='color:blue'>145</span></u><span
lang=EN-US>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
return 0;</span></p>

<p class=a><u><span lang=EN-US style='color:blue'>146</span></u><span
lang=EN-US>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; else if
(inode-&gt;i_pipe)</span></p>

<p class=a><u><span lang=EN-US style='color:blue'>147</span></u><span
lang=EN-US>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
if (inode-&gt;i_count &lt; 2)</span></p>

<p class=a><u><span lang=EN-US style='color:blue'>148</span></u><span
lang=EN-US>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
return 1;</span></p>

<p class=a><u><span lang=EN-US style='color:blue'>149</span></u><span
lang=EN-US>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
else</span></p>

<p class=a><u><span lang=EN-US style='color:blue'>150</span></u><span
lang=EN-US>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
<u><span style='color:blue'>add_wait</span></u>(&amp;inode-&gt;i_wait,<u><span
style='color:blue'>wait</span></u>);</span></p>

<p class=a><u><span lang=EN-US style='color:blue'>151</span></u><span
lang=EN-US>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return 0;</span></p>

<p class=a><u><span lang=EN-US style='color:blue'>152</span></u><span
lang=EN-US> }</span></p>

<p class=a><u><span lang=EN-US style='color:blue'>153</span></u><span
lang=EN-US> </span></p>

<p class=a><span lang=EN-US>&nbsp;&nbsp;&nbsp; // do_select() </span>是内核执行<span
lang=EN-US>select()</span>系统调用的实际处理函数。该函数首先检查描述符集中各个</p>

<p class=a><span lang=EN-US>&nbsp;&nbsp;&nbsp; // </span>描述符的有效性，然后分别调用相关描述符集描述符检查函数<span
lang=EN-US>check_XX()</span>对每个描述符进行检</p>

<p class=a><span lang=EN-US>&nbsp;&nbsp;&nbsp; // </span>查，同时统计描述符集中当前已经准备好的描述符个数。若有任何一个描述符已经准备好，本</p>

<p class=a><span lang=EN-US>&nbsp;&nbsp;&nbsp; // </span>函数就会立刻返回，否则进程就会在本函数中进入睡眠状态，并在过了超时时间或者由于某个</p>

<p class=a><span lang=EN-US>&nbsp;&nbsp;&nbsp; // </span>描述符所在等待队列上的进程被唤醒而使本进程继续运行。</p>

<p class=a><u><span lang=EN-US style='color:blue'>154</span></u><span
lang=EN-US> int <u><span style='color:blue'>do_select</span></u>(<u><span
style='color:blue'>fd_set</span></u> in, <u><span style='color:blue'>fd_set</span></u>
out, <u><span style='color:blue'>fd_set</span></u> ex,</span></p>

<p class=a><u><span lang=EN-US style='color:blue'>155</span></u><span
lang=EN-US>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <u><span
style='color:blue'>fd_set</span></u> *inp, <u><span style='color:blue'>fd_set</span></u>
*outp, <u><span style='color:blue'>fd_set</span></u> *exp)</span></p>

<p class=a><u><span lang=EN-US style='color:blue'>156</span></u><span
lang=EN-US> {</span></p>

<p class=a><u><span lang=EN-US style='color:blue'>157</span></u><span
lang=EN-US>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; int <u><span
style='color:blue'>count</span></u>;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;//
</span>已准备好的描述符个数计数值。</p>

<p class=a><u><span lang=EN-US style='color:blue'>158</span></u><span
lang=EN-US>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <u><span
style='color:blue'>select_table</span></u> wait_table;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
// </span>等待表结构。</p>

<p class=a><u><span lang=EN-US style='color:blue'>159</span></u><span
lang=EN-US>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; int i;</span></p>

<p class=a><u><span lang=EN-US style='color:blue'>160</span></u><span
lang=EN-US>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <u><span
style='color:blue'>fd_set</span></u> mask;</span></p>

<p class=a><u><span lang=EN-US style='color:blue'>161</span></u><span
lang=EN-US> </span></p>

<p class=a><span lang=EN-US>&nbsp;&nbsp;&nbsp; // </span>首先把<span lang=EN-US>3</span>个描述符集进行或操作，在<span
lang=EN-US>mask</span>中得到描述符集中有效描述符比特位屏蔽码。 然后</p>

<p class=a><span lang=EN-US>&nbsp;&nbsp;&nbsp; // </span>循环判断当前进程各个描述符是否有效并且包含在描述符集内。在循环中，每判断完一个描述</p>

<p class=a><span lang=EN-US>&nbsp;&nbsp;&nbsp; // </span>符就会把<span lang=EN-US>mask</span>右移<span
lang=EN-US>1</span>位，因此根据<span lang=EN-US>mask</span>的最低有效比特位我们就可以判断相应描述符是否在</p>

<p class=a><span lang=EN-US>&nbsp;&nbsp;&nbsp; // </span>用户给定的描述符集中。有效的描述符应该是一个管道文件描述符，或者是一个字符设备文件</p>

<p class=a><span lang=EN-US>&nbsp;&nbsp;&nbsp; // </span>描述符，或者是一个<span
lang=EN-US>FIFO</span>描述符，其余类型的都作为无效描述符而返回<span lang=EN-US>EBADF</span>错误。</p>

<p class=a><u><span lang=EN-US style='color:blue'>162</span></u><span
lang=EN-US>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; mask = in | out |
ex;</span></p>

<p class=a><u><span lang=EN-US style='color:blue'>163</span></u><span
lang=EN-US>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; for (i = 0 ; i &lt;
<u><span style='color:blue'>NR_OPEN</span></u> ; i++,mask &gt;&gt;= 1) {</span></p>

<p class=a><u><span lang=EN-US style='color:blue'>164</span></u><span
lang=EN-US>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
if (!(mask &amp; 1))&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
// </span>若不在描述符集中则继续判断下一个。</p>

<p class=a><u><span lang=EN-US style='color:blue'>165</span></u><span
lang=EN-US>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
continue;</span></p>

<p class=a><u><span lang=EN-US style='color:blue'>166</span></u><span
lang=EN-US>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
if (!<u><span style='color:blue'>current</span></u>-&gt;filp[i])&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
// </span>若该文件未打开，则返回描述符错。</p>

<p class=a><u><span lang=EN-US style='color:blue'>167</span></u><span
lang=EN-US>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
return -<u><span style='color:blue'>EBADF</span></u>;</span></p>

<p class=a><u><span lang=EN-US style='color:blue'>168</span></u><span
lang=EN-US>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
if (!<u><span style='color:blue'>current</span></u>-&gt;filp[i]-&gt;f_inode)&nbsp;
// </span>若文件<span lang=EN-US>i</span>节点指针空，则返回错误号。</p>

<p class=a><u><span lang=EN-US style='color:blue'>169</span></u><span
lang=EN-US>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
return -<u><span style='color:blue'>EBADF</span></u>;</span></p>

<p class=a><u><span lang=EN-US style='color:blue'>170</span></u><span
lang=EN-US>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
if (<u><span style='color:blue'>current</span></u>-&gt;filp[i]-&gt;f_inode-&gt;i_pipe)
// </span>若是管道文件描述符，则有效。</p>

<p class=a><u><span lang=EN-US style='color:blue'>171</span></u><span
lang=EN-US>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
continue;</span></p>

<p class=a><u><span lang=EN-US style='color:blue'>172</span></u><span
lang=EN-US>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
if (<u><span style='color:blue'>S_ISCHR</span></u>(<u><span style='color:blue'>current</span></u>-&gt;filp[i]-&gt;f_inode-&gt;i_mode))
// </span>字符设备文件有效。</p>

<p class=a><u><span lang=EN-US style='color:blue'>173</span></u><span
lang=EN-US>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
continue;</span></p>

<p class=a><u><span lang=EN-US style='color:blue'>174</span></u><span
lang=EN-US>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if
(<u><span style='color:blue'>S_ISFIFO</span></u>(<u><span style='color:blue'>current</span></u>-&gt;filp[i]-&gt;f_inode-&gt;i_mode))
// FIFO</span>也有效。</p>

<p class=a><u><span lang=EN-US style='color:blue'>175</span></u><span
lang=EN-US>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
continue;</span></p>

<p class=a><u><span lang=EN-US style='color:blue'>176</span></u><span
lang=EN-US>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
return -<u><span style='color:blue'>EBADF</span></u>;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
// </span>其余都作为无效描述符而返回。</p>

<p class=a><u><span lang=EN-US style='color:blue'>177</span></u><span
lang=EN-US>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }</span></p>

<p class=a><span lang=EN-US>&nbsp;&nbsp;&nbsp; // </span>下面开始循环检查<span
lang=EN-US>3</span>个描述符集中的各个描述符是否准备好（可以操作）。此时<span lang=EN-US>mask</span>用作当前</p>

<p class=a><span lang=EN-US>&nbsp;&nbsp;&nbsp; // </span>正在处理描述符的屏蔽码。循环中的<span
lang=EN-US>3</span>个函数<span lang=EN-US>check_in()</span>、<span lang=EN-US>check_out()</span>和<span
lang=EN-US>check_ex()</span>分别用</p>

<p class=a><span lang=EN-US>&nbsp;&nbsp;&nbsp; // </span>来判断描述符是否已经准备好。若一个描述符已经准备好，则在相关描述符集中设置对应比特</p>

<p class=a><span lang=EN-US>&nbsp;&nbsp;&nbsp; // </span>位，并且把已准备好描述符个数计数值<span
lang=EN-US>count</span>增<span lang=EN-US>1</span>。第<span lang=EN-US>183</span>行<span
lang=EN-US>for</span>循环语句中的<span lang=EN-US> mask += mask</span></p>

<p class=a><span lang=EN-US>&nbsp;&nbsp;&nbsp; // </span>等效于 <span lang=EN-US>mask&lt;&lt;
1</span>。</p>

<p class=a><u><span lang=EN-US style='color:blue'>178</span></u><span
lang=EN-US> repeat:</span></p>

<p class=a><u><span lang=EN-US style='color:blue'>179</span></u><span
lang=EN-US>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; wait_table.nr = 0;</span></p>

<p class=a><u><span lang=EN-US style='color:blue'>180</span></u><span
lang=EN-US>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; *inp = *outp = *exp
= 0;</span></p>

<p class=a><u><span lang=EN-US style='color:blue'>181</span></u><span
lang=EN-US>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <u><span
style='color:blue'>count</span></u> = 0;</span></p>

<p class=a><u><span lang=EN-US style='color:blue'>182</span></u><span
lang=EN-US>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; mask = 1;</span></p>

<p class=a><u><span lang=EN-US style='color:blue'>183</span></u><span
lang=EN-US>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; for (i = 0 ; i &lt;
<u><span style='color:blue'>NR_OPEN</span></u> ; i++, mask += mask) {</span></p>

<p class=a><span lang=EN-US>&nbsp;&nbsp;&nbsp; // </span>如果此时判断的描述符在读操作描述符集中，并且该描述符已经准备好可以进行读操作，则把</p>

<p class=a><span lang=EN-US>&nbsp;&nbsp;&nbsp; // </span>该描述符在描述符集<span
lang=EN-US>in</span>中对应比特位置为<span lang=EN-US>1</span>，同时把已准备好描述符个数计数值<span
lang=EN-US>count</span>增<span lang=EN-US>1</span>。</p>

<p class=a><u><span lang=EN-US style='color:blue'>184</span></u><span
lang=EN-US>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
if (mask &amp; in)</span></p>

<p class=a><u><span lang=EN-US style='color:blue'>185</span></u><span
lang=EN-US>&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if
(<u><span style='color:blue'>check_in</span></u>(&amp;wait_table,<u><span
style='color:blue'>current</span></u>-&gt;filp[i]-&gt;f_inode)) {</span></p>

<p class=a><u><span lang=EN-US style='color:blue'>186</span></u><span
lang=EN-US>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
*inp |= mask;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
// </span>描述符集中设置对应比特位。</p>

<p class=a><u><span lang=EN-US style='color:blue'>187</span></u><span
lang=EN-US>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
<u><span style='color:blue'>count</span></u>++;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
// </span>已准备好描述符个数计数。</p>

<p class=a><u><span lang=EN-US style='color:blue'>188</span></u><span
lang=EN-US>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp;&nbsp;}</span></p>

<p class=a><span lang=EN-US>&nbsp;&nbsp;&nbsp; // </span>如果此时判断的描述符在写操作描述符集中，并且该描述符已经准备好可以进行写操作，则把</p>

<p class=a><span lang=EN-US>&nbsp;&nbsp;&nbsp; // </span>该描述符在描述符集<span
lang=EN-US>out</span>中对应比特位置为<span lang=EN-US>1</span>，同时把已准备好描述符个数计数值<span
lang=EN-US>count</span>增<span lang=EN-US>1</span>。</p>

<p class=a><u><span lang=EN-US style='color:blue'>189</span></u><span
lang=EN-US>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
if (mask &amp; out)</span></p>

<p class=a><u><span lang=EN-US style='color:blue'>190</span></u><span
lang=EN-US>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
if (<u><span style='color:blue'>check_out</span></u>(&amp;wait_table,<u><span
style='color:blue'>current</span></u>-&gt;filp[i]-&gt;f_inode)) {</span></p>

<p class=a><u><span lang=EN-US style='color:blue'>191</span></u><span
lang=EN-US>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*outp |= mask;</span></p>

<p class=a><u><span lang=EN-US style='color:blue'>192</span></u><span
lang=EN-US>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
<u><span style='color:blue'>count</span></u>++;</span></p>

<p class=a><u><span lang=EN-US style='color:blue'>193</span></u><span
lang=EN-US>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
}</span></p>

<p class=a><span lang=EN-US>&nbsp;&nbsp;&nbsp; // </span>如果此时判断的描述符在异常描述符集中，并且该描述符已经有异常出现，则把该描述符在描</p>

<p class=a><span lang=EN-US>&nbsp;&nbsp;&nbsp; // </span>述符集<span lang=EN-US>ex</span>中对应比特位置为<span
lang=EN-US>1</span>，同时把已准备好描述符个数计数值<span lang=EN-US>count</span>增<span
lang=EN-US>1</span>。</p>

<p class=a><u><span lang=EN-US style='color:blue'>194</span></u><span
lang=EN-US>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
if (mask &amp; ex)</span></p>

<p class=a><u><span lang=EN-US style='color:blue'>195</span></u><span
lang=EN-US>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
if (<u><span style='color:blue'>check_ex</span></u>(&amp;wait_table,<u><span
style='color:blue'>current</span></u>-&gt;filp[i]-&gt;f_inode)) {</span></p>

<p class=a><u><span lang=EN-US style='color:blue'>196</span></u><span
lang=EN-US>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
*exp |= mask;</span></p>

<p class=a><u><span lang=EN-US style='color:blue'>197</span></u><span
lang=EN-US>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
<u><span style='color:blue'>count</span></u>++;</span></p>

<p class=a><u><span lang=EN-US style='color:blue'>198</span></u><span
lang=EN-US>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
}</span></p>

<p class=a><u><span lang=EN-US style='color:blue'>199</span></u><span
lang=EN-US>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }</span></p>

<p class=a><span lang=EN-US>&nbsp;&nbsp;&nbsp; // </span>在对进程所有描述符判断处理过后，若没有发现有已准备好的描述符（<span
lang=EN-US>count==0</span>），并且此时</p>

<p class=a><span lang=EN-US>&nbsp;&nbsp;&nbsp; // </span>进程没有收到任何非阻塞信号，并且此时有等待着的描述符或者等待时间还没有超时，那么我</p>

<p class=a><span lang=EN-US>&nbsp;&nbsp;&nbsp; // </span>们就把当前进程状态设置成可中断睡眠状态，然后执行调度函数去执行其他任务。当内核又一</p>

<p class=a><span lang=EN-US>&nbsp;&nbsp;&nbsp; // </span>次调度执行本任务时就调用<span
lang=EN-US>free_wait()</span>唤醒相关等待队列上本任务前后的任务，然后跳转到</p>

<p class=a><span lang=EN-US>&nbsp;&nbsp;&nbsp; // repeat</span>标号处（<span
lang=EN-US>178</span>行）再次重新检测是否有我们关心的（描述符集中的）描述符已准备好。</p>

<p class=a><u><span lang=EN-US style='color:blue'>200</span></u><span
lang=EN-US>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;if (!(<u><span
style='color:blue'>current</span></u>-&gt;signal &amp; ~current-&gt;blocked)
&amp;&amp;</span></p>

<p class=a><u><span lang=EN-US style='color:blue'>201</span></u><span
lang=EN-US>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
(wait_table.nr || <u><span style='color:blue'>current</span></u>-&gt;timeout)
&amp;&amp; !<u><span style='color:blue'>count</span></u>) {</span></p>

<p class=a><u><span lang=EN-US style='color:blue'>202</span></u><span
lang=EN-US>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
<u><span style='color:blue'>current</span></u>-&gt;<u><span style='color:blue'>state</span></u>
= <u><span style='color:blue'>TASK_INTERRUPTIBLE</span></u>;</span></p>

<p class=a><u><span lang=EN-US style='color:blue'>203</span></u><span
lang=EN-US>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
<u><span style='color:blue'>schedule</span></u>();</span></p>

<p class=a><u><span lang=EN-US style='color:blue'>204</span></u><span
lang=EN-US>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
<u><span style='color:blue'>free_wait</span></u>(&amp;wait_table);&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
// </span>本任务被唤醒返回后从这里开始执行。</p>

<p class=a><u><span lang=EN-US style='color:blue'>205</span></u><span
lang=EN-US>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
goto repeat;</span></p>

<p class=a><u><span lang=EN-US style='color:blue'>206</span></u><span
lang=EN-US>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }</span></p>

<p class=a><span lang=EN-US>&nbsp;&nbsp;&nbsp; // </span>如果此时<span lang=EN-US>count</span>不等于<span
lang=EN-US>0</span>，或者接收到了信号，或者等待时间到并且没有需要等待的描述符，</p>

<p class=a><span lang=EN-US>&nbsp;&nbsp;&nbsp; // </span>那么我们就调用<span
lang=EN-US>free_wait()</span>唤醒等待队列上的任务，然后返回已准备好的描述符个数值。</p>

<p class=a><u><span lang=EN-US style='color:blue'>207</span></u><span
lang=EN-US>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <u><span
style='color:blue'>free_wait</span></u>(&amp;wait_table);</span></p>

<p class=a><u><span lang=EN-US style='color:blue'>208</span></u><span
lang=EN-US>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return <u><span
style='color:blue'>count</span></u>;</span></p>

<p class=a><u><span lang=EN-US style='color:blue'>209</span></u><span
lang=EN-US> }</span></p>

<p class=a><u><span lang=EN-US style='color:blue'>210</span></u><span
lang=EN-US> </span></p>

<p class=a><u><span lang=EN-US style='color:blue'>211</span></u><span
lang=EN-US> <b><i>/*</i></b></span></p>

<p class=a><u><span lang=EN-US style='color:blue'>212</span></u><span
lang=EN-US> <b><i>&nbsp;* Note that we cannot return -ERESTARTSYS, as we change
our input</i></b></span></p>

<p class=a><u><span lang=EN-US style='color:blue'>213</span></u><span
lang=EN-US> <b><i>&nbsp;* parameters. Sad, but there you are. We could do some
tweaking in</i></b></span></p>

<p class=a><u><span lang=EN-US style='color:blue'>214</span></u><span
lang=EN-US> <b><i>&nbsp;* the library function ...</i></b></span></p>

<p class=a><u><span lang=EN-US style='color:blue'>215</span></u><span
lang=EN-US> <b><i>&nbsp;*/</i></b></span></p>

<p class=a><span lang=EN-US>&nbsp;&nbsp;&nbsp; /*</span></p>

<p class=a><span lang=EN-US>&nbsp;&nbsp;&nbsp;&nbsp; * </span>注意我们不能返回<span
lang=EN-US>-ERESTARTSYS</span>，因为我们会在<span lang=EN-US>select</span>运行过程中改变</p>

<p class=a><span lang=EN-US>&nbsp;&nbsp;&nbsp;&nbsp; * </span>输入参数值（<span
lang=EN-US>*timeout</span>）。很不幸，但你也只能接受这个事实。不过我们</p>

<p class=a><span lang=EN-US>&nbsp;&nbsp;&nbsp;&nbsp; * </span>可以在库函数中做些处理<span
lang=EN-US>...</span></p>

<p class=a><span lang=EN-US>&nbsp;&nbsp;&nbsp;&nbsp; */</span></p>

<p class=a><span lang=EN-US>&nbsp;&nbsp;&nbsp; // select</span>系统调用函数。该函数中的代码主要负责进行<span
lang=EN-US>select</span>功能操作前后的参数复制和转换</p>

<p class=a><span lang=EN-US>&nbsp;&nbsp;&nbsp; // </span>工作。<span lang=EN-US>select</span>主要的工作由<span
lang=EN-US>do_select()</span>函数来完成。<span lang=EN-US>sys_select()</span>会首先根据参数传递来的</p>

<p class=a><span lang=EN-US>&nbsp;&nbsp;&nbsp; // </span>缓冲区指针从用户数据空间把 <span
lang=EN-US>select() </span>函数调用的参数分解复制到内核空间，然后设置需要</p>

<p class=a><span lang=EN-US>&nbsp;&nbsp;&nbsp; // </span>等待的超时时间值<span
lang=EN-US>timeout</span>，接着调用<span lang=EN-US>do_select() </span>执行 <span
lang=EN-US>select</span>功能，返回后就把处理结果</p>

<p class=a><span lang=EN-US>&nbsp;&nbsp;&nbsp; // </span>再复制会用户空间中。</p>

<p class=a><span lang=EN-US>&nbsp;&nbsp;&nbsp; // </span>参数<span lang=EN-US>buffer</span>指向用户数据区中<span
lang=EN-US>select()</span>函数的第<span lang=EN-US>1</span>个参数处。如果返回值小于<span
lang=EN-US>0</span>表示执行时</p>

<p class=a><span lang=EN-US>&nbsp;&nbsp;&nbsp; // </span>出现错误；如果返回值等于<span
lang=EN-US>0</span>，则表示在规定等待时间内没有描述符准备好操作；如果返回值</p>

<p class=a><span lang=EN-US>&nbsp;&nbsp;&nbsp; // </span>大于<span lang=EN-US>0</span>，则表示已准备好的描述符数量。</p>

<p class=a><u><span lang=EN-US style='color:blue'>216</span></u><span
lang=EN-US> int <u><span style='color:blue'>sys_select</span></u>( unsigned
long *buffer )</span></p>

<p class=a><u><span lang=EN-US style='color:blue'>217</span></u><span
lang=EN-US> {</span></p>

<p class=a><u><span lang=EN-US style='color:blue'>218</span></u><span
lang=EN-US> <b><i>/* Perform the select(nd, in, out, ex, tv) system call. */</i></b></span></p>

<p class=a><span lang=EN-US>&nbsp;&nbsp;&nbsp; /* </span>执行<span lang=EN-US>select(nd,
in, out, ex, tv)</span>系统调用<span lang=EN-US> */</span></p>

<p class=a><span lang=EN-US>&nbsp;&nbsp;&nbsp; // </span>首先定义几个局部变量，用于把指针参数传递来的<span
lang=EN-US>select()</span>函数参数分解开来。</p>

<p class=a><u><span lang=EN-US style='color:blue'>219</span></u><span
lang=EN-US>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; int i;</span></p>

<p class=a><u><span lang=EN-US style='color:blue'>220</span></u><span
lang=EN-US>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <u><span
style='color:blue'>fd_set</span></u> res_in, in = 0, *inp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
// </span>读操作描述符集。</p>

<p class=a><u><span lang=EN-US style='color:blue'>221</span></u><span
lang=EN-US>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <u><span
style='color:blue'>fd_set</span></u> res_out, out = 0, *outp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
// </span>写操作描述符集。</p>

<p class=a><u><span lang=EN-US style='color:blue'>222</span></u><span
lang=EN-US>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <u><span
style='color:blue'>fd_set</span></u> res_ex, ex = 0, *exp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
// </span>异常条件描述符集。</p>

<p class=a><u><span lang=EN-US style='color:blue'>223</span></u><span
lang=EN-US>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <u><span
style='color:blue'>fd_set</span></u> mask;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
// </span>处理的描述符数值范围（<span lang=EN-US>nd</span>）屏蔽码。</p>

<p class=a><u><span lang=EN-US style='color:blue'>224</span></u><span
lang=EN-US>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; struct <u><span
style='color:blue'>timeval</span></u> *tvp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
// </span>等待时间结构指针。</p>

<p class=a><u><span lang=EN-US style='color:blue'>225</span></u><span
lang=EN-US>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; unsigned long
timeout;</span></p>

<p class=a><u><span lang=EN-US style='color:blue'>226</span></u><span
lang=EN-US> </span></p>

<p class=a><span lang=EN-US>&nbsp;&nbsp;&nbsp; // </span>然后从用户数据区把参数分别隔离复制到局部指针变量中，并根据描述符集指针是否有效分别</p>

<p class=a><span lang=EN-US>&nbsp;&nbsp;&nbsp; // </span>取得<span lang=EN-US>3</span>个描述符集<span
lang=EN-US>in</span>（读）、<span lang=EN-US>out</span>（写）和<span lang=EN-US>ex</span>（异常）。其中
<span lang=EN-US>mask </span>也是一个描述符集变量，</p>

<p class=a><span lang=EN-US>&nbsp;&nbsp;&nbsp; // </span>根据<span lang=EN-US>3</span>个描述符集中最大描述符数值<span
lang=EN-US>+1</span>（即第<span lang=EN-US>1</span>个参数<span lang=EN-US>nd</span>的值），它被设置成用户程序关心的</p>

<p class=a><span lang=EN-US>&nbsp;&nbsp;&nbsp; // </span>所有描述符的屏蔽码。例如，若<span
lang=EN-US>nd = 4</span>，则<span lang=EN-US>mask = 0b00001111</span>（共<span
lang=EN-US>32</span>比特）。</p>

<p class=a><u><span lang=EN-US style='color:blue'>227</span></u><span
lang=EN-US>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; mask = ~((~0)
&lt;&lt; <u><span style='color:blue'>get_fs_long</span></u>(buffer++));</span></p>

<p class=a><u><span lang=EN-US style='color:blue'>228</span></u><span
lang=EN-US>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; inp = (<u><span
style='color:blue'>fd_set</span></u> *) <u><span style='color:blue'>get_fs_long</span></u>(buffer++);</span></p>

<p class=a><u><span lang=EN-US style='color:blue'>229</span></u><span
lang=EN-US>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; outp = (<u><span
style='color:blue'>fd_set</span></u> *) <u><span style='color:blue'>get_fs_long</span></u>(buffer++);</span></p>

<p class=a><u><span lang=EN-US style='color:blue'>230</span></u><span
lang=EN-US>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; exp = (<u><span
style='color:blue'>fd_set</span></u> *) <u><span style='color:blue'>get_fs_long</span></u>(buffer++);</span></p>

<p class=a><u><span lang=EN-US style='color:blue'>231</span></u><span
lang=EN-US>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; tvp = (struct <u><span
style='color:blue'>timeval</span></u> *) <u><span style='color:blue'>get_fs_long</span></u>(buffer);</span></p>

<p class=a><u><span lang=EN-US style='color:blue'>232</span></u><span
lang=EN-US> </span></p>

<p class=a><u><span lang=EN-US style='color:blue'>233</span></u><span
lang=EN-US>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (inp)&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
// </span>若指针有效，则取读操作描述符集。</p>

<p class=a><u><span lang=EN-US style='color:blue'>234</span></u><span
lang=EN-US>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
in = mask &amp; <u><span style='color:blue'>get_fs_long</span></u>(inp);</span></p>

<p class=a><u><span lang=EN-US style='color:blue'>235</span></u><span
lang=EN-US>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (outp)&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
// </span>若指针有效，则取写操作描述符集。</p>

<p class=a><u><span lang=EN-US style='color:blue'>236</span></u><span
lang=EN-US>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
out = mask &amp; <u><span style='color:blue'>get_fs_long</span></u>(outp);</span></p>

<p class=a><u><span lang=EN-US style='color:blue'>237</span></u><span
lang=EN-US>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (exp)&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
// </span>若指针有效，则取异常描述符集。</p>

<p class=a><u><span lang=EN-US style='color:blue'>238</span></u><span
lang=EN-US>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
ex = mask &amp; <u><span style='color:blue'>get_fs_long</span></u>(exp);</span></p>

<p class=a><span lang=EN-US>&nbsp;&nbsp;&nbsp; // </span>接下来我们尝试从时间结构中取出等待（睡眠）时间值<span
lang=EN-US>timeout</span>。首先把<span lang=EN-US>timeout</span>初始化成最大</p>

<p class=a><span lang=EN-US>&nbsp;&nbsp;&nbsp; // </span>（无限）值，然后从用户数据空间取得该时间结构中设置的时间值，经转换和加上系统当前滴答</p>

<p class=a><span lang=EN-US>&nbsp;&nbsp;&nbsp; // </span>值<span lang=EN-US>jiffies</span>，最后得到需要等待的时间滴答数值
<span lang=EN-US>timeout</span>。我们用此值来设置当前进程应该等待</p>

<p class=a><span lang=EN-US>&nbsp;&nbsp;&nbsp; // </span>的延时。另外，第<span
lang=EN-US>241</span>行上<span lang=EN-US>tv_usec</span>字段是微秒值，把它除以<span
lang=EN-US>1000000</span>后可得到对应秒数，再乘</p>

<p class=a><span lang=EN-US>&nbsp;&nbsp;&nbsp; // </span>以系统每秒滴答数<span
lang=EN-US>HZ</span>，即把<span lang=EN-US>tv_usec</span>转换成滴答值。</p>

<p class=a><u><span lang=EN-US style='color:blue'>239</span></u><span
lang=EN-US>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; timeout =
0xffffffff;</span></p>

<p class=a><u><span lang=EN-US style='color:blue'>240</span></u><span
lang=EN-US>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (tvp) {</span></p>

<p class=a><u><span lang=EN-US style='color:blue'>241</span></u><span
lang=EN-US>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
timeout = <u><span style='color:blue'>get_fs_long</span></u>((unsigned long
*)&amp;tvp-&gt;tv_usec)/(1000000/<u><span style='color:blue'>HZ</span></u>);</span></p>

<p class=a><u><span lang=EN-US style='color:blue'>242</span></u><span
lang=EN-US>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
timeout += <u><span style='color:blue'>get_fs_long</span></u>((unsigned long
*)&amp;tvp-&gt;tv_sec) * <u><span style='color:blue'>HZ</span></u>;</span></p>

<p class=a><u><span lang=EN-US style='color:blue'>243</span></u><span
lang=EN-US>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
timeout += <u><span style='color:blue'>jiffies</span></u>;</span></p>

<p class=a><u><span lang=EN-US style='color:blue'>244</span></u><span
lang=EN-US>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }</span></p>

<p class=a><u><span lang=EN-US style='color:blue'>245</span></u><span
lang=EN-US>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <u><span
style='color:blue'>current</span></u>-&gt;timeout = timeout;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
&nbsp;// </span>设置当前进程应该延时的滴答值。</p>

<p class=a><span lang=EN-US>&nbsp;&nbsp;&nbsp; // select()</span>函数的主要工作在<span
lang=EN-US>do_select()</span>中完成。在调用该函数之后的代码用于把处理结果复制</p>

<p class=a><span lang=EN-US>&nbsp;&nbsp;&nbsp; // </span>到用户数据区中，返回给用户。为了避免出现竞争条件，在调用<span
lang=EN-US>do_select()</span>前需要禁止中断，</p>

<p class=a><span lang=EN-US>&nbsp;&nbsp;&nbsp; // </span>并在该函数返回后再开启中断。</p>

<p class=a><span lang=EN-US>&nbsp;&nbsp;&nbsp; // </span>如果在<span lang=EN-US>do_select()</span>返回之后进程的等待延时字段<span
lang=EN-US>timeout</span>还大于当前系统计时滴答值<span lang=EN-US>jiffies</span>，</p>

<p class=a><span lang=EN-US>&nbsp;&nbsp;&nbsp; // </span>说明在超时之前已经有描述符准备好，于是这里我们先记下到超时还剩余的时间值，随后我们会</p>

<p class=a><span lang=EN-US>&nbsp;&nbsp;&nbsp; // </span>把这个值返回给用户。如果进程的等待延时字段<span
lang=EN-US>timeout</span>已经小于或等于当前系统<span lang=EN-US>jiffies</span>，表</p>

<p class=a><span lang=EN-US>&nbsp;&nbsp;&nbsp; // </span>示<span lang=EN-US>do_select()</span>可能是由于超时而返回，因此把剩余时间值设置为<span
lang=EN-US>0</span>。</p>

<p class=a><u><span lang=EN-US style='color:blue'>246</span></u><span
lang=EN-US>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <u><span
style='color:blue'>cli</span></u>();&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
// </span>禁止响应中断。</p>

<p class=a><u><span lang=EN-US style='color:blue'>247</span></u><span
lang=EN-US>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; i = <u><span
style='color:blue'>do_select</span></u>(in, out, ex, &amp;res_in, &amp;res_out,
&amp;res_ex);</span></p>

<p class=a><u><span lang=EN-US style='color:blue'>248</span></u><span
lang=EN-US>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (<u><span
style='color:blue'>current</span></u>-&gt;timeout &gt; <u><span
style='color:blue'>jiffies</span></u>)</span></p>

<p class=a><u><span lang=EN-US style='color:blue'>249</span></u><span
lang=EN-US>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
timeout = <u><span style='color:blue'>current</span></u>-&gt;timeout - <u><span
style='color:blue'>jiffies</span></u>;</span></p>

<p class=a><u><span lang=EN-US style='color:blue'>250</span></u><span
lang=EN-US>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; else</span></p>

<p class=a><u><span lang=EN-US style='color:blue'>251</span></u><span
lang=EN-US>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
timeout = 0;</span></p>

<p class=a><u><span lang=EN-US style='color:blue'>252</span></u><span
lang=EN-US>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <u><span
style='color:blue'>sti</span></u>();&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
// </span>开启中断响应。</p>

<p class=a><span lang=EN-US>&nbsp;&nbsp;&nbsp; // </span>接下来我们把进程的超时字段清零。如果<span
lang=EN-US>do_select()</span>返回的已准备好描述符个数小于<span lang=EN-US>0</span>，表示</p>

<p class=a><span lang=EN-US>&nbsp;&nbsp;&nbsp; // </span>执行出错，于是返回这个错误号。然后我们把处理过的描述符集内容和延迟时间结构内容写回到</p>

<p class=a><span lang=EN-US>&nbsp;&nbsp;&nbsp; // </span>用户数据缓冲空间。在写时间结构内容时还需要先将滴答时间单位表示的剩余延迟时间转换成秒</p>

<p class=a><span lang=EN-US>&nbsp;&nbsp;&nbsp; // </span>和微秒值。</p>

<p class=a><u><span lang=EN-US style='color:blue'>253</span></u><span
lang=EN-US>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <u><span
style='color:blue'>current</span></u>-&gt;timeout = 0;</span></p>

<p class=a><u><span lang=EN-US style='color:blue'>254</span></u><span
lang=EN-US>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (i &lt; 0)</span></p>

<p class=a><u><span lang=EN-US style='color:blue'>255</span></u><span
lang=EN-US>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
return i;</span></p>

<p class=a><u><span lang=EN-US style='color:blue'>256</span></u><span
lang=EN-US>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (inp) {</span></p>

<p class=a><u><span lang=EN-US style='color:blue'>257</span></u><span
lang=EN-US>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
<u><span style='color:blue'>verify_area</span></u>(inp, 4);</span></p>

<p class=a><u><span lang=EN-US style='color:blue'>258</span></u><span
lang=EN-US>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
<u><span style='color:blue'>put_fs_long</span></u>(res_in,inp);&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
// </span>可读描述符集。</p>

<p class=a><u><span lang=EN-US style='color:blue'>259</span></u><span
lang=EN-US>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }</span></p>

<p class=a><u><span lang=EN-US style='color:blue'>260</span></u><span
lang=EN-US>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (outp) {</span></p>

<p class=a><u><span lang=EN-US style='color:blue'>261</span></u><span
lang=EN-US>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
<u><span style='color:blue'>verify_area</span></u>(outp,4);</span></p>

<p class=a><u><span lang=EN-US style='color:blue'>262</span></u><span
lang=EN-US>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
<u><span style='color:blue'>put_fs_long</span></u>(res_out,outp);&nbsp;&nbsp;&nbsp;&nbsp;
// </span>可写描述符集。</p>

<p class=a><u><span lang=EN-US style='color:blue'>263</span></u><span
lang=EN-US>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }</span></p>

<p class=a><u><span lang=EN-US style='color:blue'>264</span></u><span
lang=EN-US>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (exp) {</span></p>

<p class=a><u><span lang=EN-US style='color:blue'>265</span></u><span
lang=EN-US>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
<u><span style='color:blue'>verify_area</span></u>(exp,4);</span></p>

<p class=a><u><span lang=EN-US style='color:blue'>266</span></u><span
lang=EN-US>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
<u><span style='color:blue'>put_fs_long</span></u>(res_ex,exp);&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
// </span>出现异常条件描述符集。</p>

<p class=a><u><span lang=EN-US style='color:blue'>267</span></u><span
lang=EN-US>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }</span></p>

<p class=a><u><span lang=EN-US style='color:blue'>268</span></u><span
lang=EN-US>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (tvp) {</span></p>

<p class=a><u><span lang=EN-US style='color:blue'>269</span></u><span
lang=EN-US>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
<u><span style='color:blue'>verify_area</span></u>(tvp, sizeof(*tvp));</span></p>

<p class=a><u><span lang=EN-US style='color:blue'>270</span></u><span
lang=EN-US>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
<u><span style='color:blue'>put_fs_long</span></u>(timeout/<u><span
style='color:blue'>HZ</span></u>, (unsigned long *) &amp;tvp-&gt;tv_sec);&nbsp;
// </span>秒。</p>

<p class=a><u><span lang=EN-US style='color:blue'>271</span></u><span
lang=EN-US>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
timeout %= <u><span style='color:blue'>HZ</span></u>;</span></p>

<p class=a><u><span lang=EN-US style='color:blue'>272</span></u><span
lang=EN-US>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
timeout *= (1000000/<u><span style='color:blue'>HZ</span></u>);</span></p>

<p class=a><u><span lang=EN-US style='color:blue'>273</span></u><span
lang=EN-US>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
<u><span style='color:blue'>put_fs_long</span></u>(timeout, (unsigned long *)
&amp;tvp-&gt;tv_usec);&nbsp; // </span>微秒。</p>

<p class=a><u><span lang=EN-US style='color:blue'>274</span></u><span
lang=EN-US>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }</span></p>

<p class=a><span lang=EN-US>&nbsp;&nbsp;&nbsp; // </span>如果此时并没有已准备好的描述符，并且收到了某个非阻塞信号，则返回被中断错误号。</p>

<p class=a><span lang=EN-US>&nbsp;&nbsp;&nbsp; // </span>否则返回已准备好的描述符个数值。</p>

<p class=a><u><span lang=EN-US style='color:blue'>275</span></u><span
lang=EN-US>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (!i &amp;&amp; (<u><span
style='color:blue'>current</span></u>-&gt;signal &amp; ~current-&gt;blocked))</span></p>

<p class=a><u><span lang=EN-US style='color:blue'>276</span></u><span
lang=EN-US>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
return -<u><span style='color:blue'>EINTR</span></u>;</span></p>

<p class=a><u><span lang=EN-US style='color:blue'>277</span></u><span
lang=EN-US>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return i;</span></p>

<p class=a><u><span lang=EN-US style='color:blue'>278</span></u><span
lang=EN-US> }</span></p>

<p class=a><u><span lang=EN-US style='color:blue'>279</span></u><span
lang=EN-US> </span></p>

<div class=a align=center style='text-align:center'><span lang=EN-US>

<hr size=4 width="100%" align=center>

</span></div>

<p class=MsoNormal><span lang=EN-US>&nbsp;</span></p>

<p class=MsoNormal><span lang=EN-US>&nbsp;</span></p>

</div>

</body>

</html>
